프록시 팩토리 적용

V1 - 인터페이스 적용

@RequiredArgsConstructor
public class LogTraceAdvice implements MethodInterceptor {

    private final LogTrace logTrace;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        TraceStatus status = null;
        try {
            Method method = invocation.getMethod();
            String message = method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()";

            status = logTrace.begin(message);
            Object result = invocation.proceed();

            logTrace.end(status);
            return result;
        } catch (Exception e) {
            logTrace.exception(status, e);
            throw e;
        }
    }
}
  • 포인트컷은 NameMatchMethodPointcut을 사용한다. 여기에는 심플 매칭 기능이 있어서 *을 매칭할 수 있다.

  • 어드바이저는 포인트컷(NameMatchMethodPointcut), 어드바이스(LogTraceAdvice)를 가지고 있다.

  • 프록시 팩토리에 각각의 targetadvice를 등록해서 프록시를 생성한다. 그리고 생성된 프록시를 스프링 빈으로 등록한다.

V2 - 구체 클래스 적용

  • 프록시 팩토리에 넣어주는 인스턴스에 따라서 프록시 팩토리가 알아서 프록시를 생성해주므로 개발자가 직접 구분할 필요가 없다.

프록시 팩토리 정리

프록시 팩토리 덕분에 편리하게 프록시를 생성할 수 있게 되었다. 그리고 어드바이저, 어드바이스, 포인트컷 이라는 개념 덕분에 어떤 부가 기능을 어디에 적용할 지 이해할 수 있었다.

문제1

  • 너무 많은 설정

  • 애플리케이션에 있는 모든 스프링 빈의 프록시를 통해 부가 기능을 적용하려면 스프링 빈의 등록된 수만큼 동적 프록시 생성 코드를 만들어야 한다.

  • 중복되는 코드도 많고 설정에만 오랜 시간이 걸릴 것이다.

문제2

  • 컴포넌트 스캔

  • 컴포넌트 스캔으로 자동 스프링 빈 등록을 사용하는 경우에는 프록시 적용이 불가능하다.

  • 왜냐하면 실제 객체를 컴포넌트 스캔으로 스프링 컨테이너에 스프링 빈으로 이미 등록을 다 해버린 상태이기 때문이다.

  • 프록시를 적용하려면 실제 객체를 등록하는 것이 아니라 부가 기능이 있는 프록시를 스프링 컨테이너에 빈으로 등록해야 한다.

이 문제를 해결하는 방법으로 빈 후처리기가 있다.

Last updated