목차
참고
본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다.
인터페이스 객체에 프록시 팩토리 적용
스프링에서 제공하는 MethodInterceptor 인터페이스를 이용해
import org.aopalliance.intercept.MethodInterceptor;
public class LogTraceAdvice implements MethodInterceptor {
private final LogTrace logTrace;
public LogTraceAdvice(LogTrace logTrace) { this.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 ex) { logTrace.exception(status, ex); throw ex; } } }
|
@Slf4j @Configuration public class ProxyFactoryConfigV1 {
@Bean public OrderControllerV1 orderControllerV1(LogTrace logTrace){ OrderControllerV1 orderController = new OrderControllerV1Impl(orderServiceV1(logTrace));
ProxyFactory factory = new ProxyFactory(orderController); factory.addAdvisor(getAdvisor(logTrace)); OrderControllerV1 proxy = (OrderControllerV1) factory.getProxy();
log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderController);
return proxy; }
@Bean public OrderServiceV1 orderServiceV1(LogTrace logTrace){ OrderServiceV1Impl orderService = new OrderServiceV1Impl(orderRepositoryV1(logTrace));
ProxyFactory factory = new ProxyFactory(orderService); factory.addAdvisor(getAdvisor(logTrace)); OrderServiceV1 proxy = (OrderServiceV1) factory.getProxy();
log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderService);
return proxy; }
@Bean public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace){ OrderRepositoryV1Impl orderRepository = new OrderRepositoryV1Impl();
ProxyFactory factory = new ProxyFactory(orderRepository); factory.addAdvisor(getAdvisor(logTrace)); OrderRepositoryV1 proxy = (OrderRepositoryV1) factory.getProxy(); log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderRepository);
return proxy; }
private Advisor getAdvisor(LogTrace logTrace) { NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); pointcut.setMappedNames("request*", "order*", "save*");
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice); } }
|
애플리케이션 로딩 시점에서 해당 Bean 이 Loading 되는 것을 확인할 수 있다.
2021-12-05 01:09:21.671 INFO 64531 --- [ main] h.p.c.v.ProxyFactoryConfigV1 : ProxyFactory proxy = class com.sun.proxy.$Proxy50, target = hello.proxy.app.v1.OrderRepositoryV1Impl@5555ffcf 2021-12-05 01:09:21.673 INFO 64531 --- [ main] h.p.c.v.ProxyFactoryConfigV1 : ProxyFactory proxy = class com.sun.proxy.$Proxy52, target = hello.proxy.app.v1.OrderServiceV1Impl@5a2fa51f 2021-12-05 01:09:21.674 INFO 64531 --- [ main] h.p.c.v.ProxyFactoryConfigV1 : ProxyFactory proxy = class com.sun.proxy.$Proxy53, target = hello.proxy.app.v1.OrderControllerV1Impl@6ecdbab8
|
구체클래스에 프록시 팩토리 적용
구체 클래스에 적용
@Slf4j @Configuration public class ProxyFactoryConfigV2 {
@Bean public OrderControllerV2 orderControllerV2(LogTrace logTrace){ OrderControllerV2 orderController = new OrderControllerV2(orderServiceV2(logTrace));
ProxyFactory factory = new ProxyFactory(orderController); factory.addAdvisor(getAdvisor(logTrace)); OrderControllerV2 proxy = (OrderControllerV2) factory.getProxy();
log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderController);
return proxy; }
@Bean public OrderServiceV2 orderServiceV2(LogTrace logTrace){ OrderServiceV2 orderService = new OrderServiceV2(orderRepositoryV2(logTrace));
ProxyFactory factory = new ProxyFactory(orderService); factory.addAdvisor(getAdvisor(logTrace)); OrderServiceV2 proxy = (OrderServiceV2) factory.getProxy();
log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderService);
return proxy; }
@Bean public OrderRepositoryV2 orderRepositoryV2(LogTrace logTrace){ OrderRepositoryV2 orderRepository = new OrderRepositoryV2();
ProxyFactory factory = new ProxyFactory(orderRepository); factory.addAdvisor(getAdvisor(logTrace)); OrderRepositoryV2 proxy = (OrderRepositoryV2) factory.getProxy(); log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderRepository);
return proxy; }
private Advisor getAdvisor(LogTrace logTrace) {
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); pointcut.setMappedNames("request*", "order*", "save*");
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice); } }
|
CGLIB 로 생성된 것을 확인할 수 있다.
2021-12-05 01:18:11.287 INFO 64747 --- [ main] h.p.c.v.ProxyFactoryConfigV2 : ProxyFactory proxy = class hello.proxy.app.v2.OrderRepositoryV2$$EnhancerBySpringCGLIB$$47389dce, target = hello.proxy.app.v2.OrderRepositoryV2@75961f16 2021-12-05 01:18:11.292 INFO 64747 --- [ main] h.p.c.v.ProxyFactoryConfigV2 : ProxyFactory proxy = class hello.proxy.app.v2.OrderServiceV2$$EnhancerBySpringCGLIB$$9b88cbf1, target = hello.proxy.app.v2.OrderServiceV2@2dd2e270 2021-12-05 01:18:11.295 INFO 64747 --- [ main] h.p.c.v.ProxyFactoryConfigV2 : ProxyFactory proxy = class hello.proxy.app.v2.OrderControllerV2$$EnhancerBySpringCGLIB$$493fc484, target = hello.proxy.app.v2.OrderControllerV2@7d04529c
|