Spring 핵심원리 고급편 - Dynamic Proxy 2
목차 Spring 핵심원리 고급편 - CGLIB Spring 핵심원리 고급편 - Dynamic Proxy 2 Spring 핵심원리 고급편 - Dynamic Proxy 1 Spring 핵심원리 고급편 - 리플렉션 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2 Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 Spring 핵심원리 고급편 - 인터페이스 프록시 1 Spring 핵심원리 고급편 - Decorator Pattern 2 Spring 핵심원리 고급편 - Decorator Pattern 1 Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스 Spring 핵심원리 고급편 - Proxy 패턴 Spring 핵심원리 고급편 - Strategy 패턴 Spring 핵심원리 고급편 - Template Method 패턴 public class LogTraceBasicHandler implements InvocationHandler { private final Object target; private final LogTrace logTrace; public LogTraceBasicHandler(Object target, LogTrace logTrace) { this.target = target; this.logTrace = logTrace; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { TraceStatus status = null; try { String message = method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()"; status = logTrace.begin(message); // 로직 호출 method.invoke(target, args); logTrace.end(status); return result; } catch (Exception ex) { logTrace.exception(status, ex); throw ex; } }} @Configurationpublic class DynamicBasicProxyConfig { @Bean public OrderControllerV1 orderControllerV1(LogTrace logTrace){ OrderControllerV1 orderControllerV1 = new OrderControllerV1Impl(orderServiceV1(logTrace)); // Proxy 객체 생성 OrderControllerV1 proxy = (OrderControllerV1) Proxy .newProxyInstance( OrderControllerV1.class.getClassLoader(), new Class[]{OrderControllerV1.class}, new LogTraceBasicHandler(orderControllerV1, logTrace)); return proxy; } @Bean public OrderServiceV1 orderServiceV1(LogTrace logTrace){ OrderServiceV1 orderServiceV1 = new OrderServiceV1Impl(orderRepositoryV1(logTrace)); // Proxy 객체 생성 OrderServiceV1 proxy = (OrderServiceV1) Proxy .newProxyInstance( OrderServiceV1.class.getClassLoader(), new Class[]{OrderServiceV1.class}, new LogTraceBasicHandler(orderServiceV1, logTrace)); return proxy; } @Bean public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace){ OrderRepositoryV1 orderRepository = new OrderRepositoryV1Impl(); // Proxy 객체 생성 OrderRepositoryV1 proxy = (OrderRepositoryV1) Proxy .newProxyInstance( OrderRepositoryV1.class.getClassLoader(), new Class[]{OrderRepositoryV1.class}, new LogTraceBasicHandler(orderRepository, logTrace)); return proxy; }} @Import(DynamicBasicProxyConfig.class)@SpringBootApplication(scanBasePackages = "hello.proxy.app") //주의public class ProxyApplication { public static void main(String[] args) { SpringApplication.run(ProxyApplication.class, args); } @Bean public LogTrace logTrace(){ return new ThreadLocalLogTrace(); }} 2021-11-28 22:18:58.331 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] OrderControllerV1.request()2021-11-28 22:18:58.333 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] |-->OrderServiceV1.orderItem()2021-11-28 22:18:58.333 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] | |-->OrderRepositoryV1.save()2021-11-28 22:18:59.338 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] | |<--OrderRepositoryV1.save() time=1005ms2021-11-28 22:18:59.338 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] |<--OrderServiceV1.orderItem() time=1006ms2021-11-28 22:18:59.339 INFO 3357 --- [nio-8080-exec-1] h.p.trace.logtrace.ThreadLocalLogTrace : [4e72efcd] OrderControllerV1.request() time=1007ms 특정 메소드에만 부가기능 로직 적용PatternMatchUtils.simpleMatch 를 사용해 메소드 이름이 조건을 만족하는지 Pattern Matching 한다.