Spring/Spring

[Spring][AOP] 1. Advice API

noahkim_ 2025. 4. 9. 17:25

1. Advice 생명 주기

구분 Per-Class (공유 인스턴스)
Per-Instance (객체별 인스턴스)
적용 방식 모든 대상 객체에서 동일한 Advice 인스턴스 공유
각 대상 객체마다 별도의 Advice 인스턴스 생성
상태 관리 Stateless Stateful
사용 사례 - 트랜잭션 관리
- 로깅
- 보안 검사
- Mixin 패턴 구현
- Introduction (인터페이스 동적 추가)
성능 메모리 사용량이 적고 효율적
객체마다 인스턴스 생성 → 메모리 오버헤드 가능성
대상 모든 메서드 호출에 공통 적용
특정 객체에 한정된 확장 기능 적용
Spring AOP 지원 기본 방식 (JDK 동적 프록시/CGLIB)
@Aspect(perthis, pertarget)

 

2. Advice 유형

Advice 종류 실행 시점 반환값 변경 예외 처리 사용 목적 / 특징
Around Advice
(MethodInterceptor)
실행 전/후/예외 시 메서드 실행 전후, 예외 모두 제어
Before Advice
(MethodBeforeAdvice)
메서드 실행 전 메서드 실행 전 검증, 로깅 등 사전 처리
After Returning
(AfterReturningAdvice)
정상 종료 후 반환값 로깅, 통계 등
Throws Advice
(ThrowsAdvice)
예외 발생 시 예외 처리 및 예외 로깅
Introduction Advice
(IntroductionInterceptor)
(IntroductionAdvisor)
런타임 시
인터페이스 주입
새로운 인터페이스/기능(Mixin) 동적 추가

 

예제) Around Advice

더보기
더보기
public class DebugInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: " + invocation);
        Object result = invocation.proceed(); // 실제 메서드 실행
        System.out.println("After");
        return result;
    }
}

 

예제) Before Advice

더보기
더보기
public class DebugInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: " + invocation);
        Object result = invocation.proceed(); // 실제 메서드 실행
        System.out.println("After");
        return result;
    }
}

 

 

예제) After Returning

더보기
더보기
public class CountingAfterReturningAdvice implements AfterReturningAdvice {
    private int count;

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        count++;
    }
    
    public int getCount() { return count; }
}

 

 

예제) Throws Advice

더보기
더보기
public class IllegalArgumentExceptionThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(IllegalArgumentException ex) {
        System.out.println("exception!");
        System.out.println(ex.getMessage());
    }

    public void afterThrowing(Method m, Object[] args, Object target, IllegalArgumentException ex) {
        System.out.println("exception!");
        System.out.println("[method] " + m.getName());
        System.out.println("[args] ");
        for (Object arg : args) System.out.println(" - " + arg);

        System.out.println("[object] " + target.getClass().getName());
        System.out.println("[exception message] " + ex.getMessage());
    }
}

 

 

예제) Introduction Advice

더보기
더보기
public interface Lockable {
    void lock();
    void unlock();
    boolean locked();
}
public class LockMixin extends DelegatingIntroductionInterceptor implements Lockable {

    private boolean locked;

    @Override
    public void lock() {
        this.locked = true;
    }

    @Override
    public void unlock() {
        this.locked = false;
    }

    @Override
    public boolean locked() {
        return this.locked;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        if (locked() && invocation.getMethod().getName().startsWith("set")) throw new LockedException();

        return super.invoke(invocation);
    }

    class LockedException extends RuntimeException {}
}
public class LockMixinAdvisor extends DefaultIntroductionAdvisor {
    public LockMixinAdvisor() {
        super(new LockMixin(), Lockable.class);
    }
}
MyService original = new MyService();

ProxyFactory pf = new ProxyFactory(original);
pf.addAdvisor(new DefaultIntroductionAdvisor(new LockMixin(), Lockable.class));

Object proxy = pf.getProxy();

((MyService) proxy).doWork();              // 원래 기능
((Lockable) proxy).lock();                 // 새로 추가된 기능!
System.out.println(((Lockable) proxy).isLocked());  // true
  • 프록시에 Advisor를 주입하면서 새로운 인터페이스까지 도입함
  • 마치 원래 객체가 그 인터페이스를 구현한 것처럼 보이게 만듬

 

 


출처

'Spring > Spring' 카테고리의 다른 글

[Spring][AOP] 3. Advisor API  (0) 2025.04.09
[Spring][AOP] 2. Pointcut API  (1) 2025.04.09
[Spring][Validation] 2. Java Bean Validation  (0) 2025.04.06
[Spring][Validation] 1. Validator Interface  (0) 2025.04.06
[Spring][Object] 1. Data Binding  (0) 2025.04.06