@Aspect 관점(Aspect) 정의 클래스 공통 관심사를 정의한 클래스를 표시. AOP로 처리할 로직이 들어있는 클래스임을 알림
@Pointcut 포인트컷 정의 메서드 공통적으로 사용할 pointcut 표현식을 별도로 정의할 때 사용
@Before 메서드 실행 전 실행 메서드 JoinPoint(대상 메서드) 실행 전에 실행되는 Advice 정의
@After 메서드 실행 후 (성공/예외 관계없이) 메서드 메서드 실행 후 무조건 수행되는 후처리
@AfterReturning 정상 반환 후 실행 메서드 메서드가 예외 없이 성공적으로 리턴될 때 실행
@AfterThrowing 예외 발생 시 실행 메서드 메서드 실행 중 예외가 발생하면 실행
@Around 메서드 전후 전체 감싸기 메서드 메서드 호출 전·후를 모두 제어할 수 있음 (가장 강력한 Advice)

@Before()같은 경우 대상 포인트컷을 애너테이션으로 지정할 수도 있음.

@annotation(애너테이션) — 메서드 레벨 지정

특정 메서드에 애너테이션이 붙어있으면 AOP적용

@Aspect
@Component
public class LoggingAspect {

    @Around("@annotation(com.example.LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();

        System.out.println(joinPoint.getSignature() + " 실행시간: " + (end - start) + "ms");
        return result;
    }
}
@Service
public class MemberService {

    @LogExecutionTime
    public void process() {
        // 로직
    }
}

@within(애너테이션) — 클래스 레벨 지정

@Aspect
@Component
public class ClassLoggingAspect {

    @Before("@within(com.example.LoggedClass)")
    public void beforeClassMethods(JoinPoint joinPoint) {
        System.out.println("[클래스 단위 로깅] " + joinPoint.getSignature());
    }
}
@LoggedClass
@Service
public class OrderService {
    public void createOrder() {}
    public void cancelOrder() {}
}

@target(애너테이션) — 런타임 시점의 프록시 클래스 기준

@Before("@target(com.example.LoggedClass)")
public void beforeTarget(JoinPoint joinPoint) {
    System.out.println("실행 대상 클래스에 LoggedClass 존재");
}

@args(애너테이션) — 메서드 인자에 붙은 애너테이션 기준