From a7cef6704a2c8dd54d7c1648658d6bfc9c23aedc Mon Sep 17 00:00:00 2001 From: haerong22 Date: Tue, 16 Nov 2021 02:38:16 +0900 Subject: [PATCH] spring core proxy : log trace - jdk dynamic proxy --- .../com/example/proxy/ProxyApplication.java | 6 ++- .../DynamicProxyBasicConfig.java | 52 ++++++++++++++++++ .../DynamicProxyFilterConfig.java | 54 +++++++++++++++++++ .../handler/LogTraceBasicHandler.java | 34 ++++++++++++ .../handler/LogTraceFilterHandler.java | 45 ++++++++++++++++ 5 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyBasicConfig.java create mode 100644 spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyFilterConfig.java create mode 100644 spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceBasicHandler.java create mode 100644 spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceFilterHandler.java diff --git a/spring-core/proxy/src/main/java/com/example/proxy/ProxyApplication.java b/spring-core/proxy/src/main/java/com/example/proxy/ProxyApplication.java index 04b39c9a..fb89a253 100644 --- a/spring-core/proxy/src/main/java/com/example/proxy/ProxyApplication.java +++ b/spring-core/proxy/src/main/java/com/example/proxy/ProxyApplication.java @@ -4,6 +4,8 @@ import com.example.proxy.config.AppV1Config; import com.example.proxy.config.AppV2Config; import com.example.proxy.config.v1_proxy.ConcreteProxyConfig; import com.example.proxy.config.v1_proxy.InterfaceProxyConfig; +import com.example.proxy.config.v2_dynamicproxy.DynamicProxyBasicConfig; +import com.example.proxy.config.v2_dynamicproxy.DynamicProxyFilterConfig; import com.example.proxy.trace.logtrace.LogTrace; import com.example.proxy.trace.logtrace.ThreadLocalLogTrace; import org.springframework.boot.SpringApplication; @@ -13,7 +15,9 @@ import org.springframework.context.annotation.Import; //@Import({AppV1Config.class, AppV2Config.class}) //@Import(InterfaceProxyConfig.class) -@Import(ConcreteProxyConfig.class) +//@Import(ConcreteProxyConfig.class) +//@Import(DynamicProxyBasicConfig.class) +@Import(DynamicProxyFilterConfig.class) @SpringBootApplication(scanBasePackages = "com.example.proxy.app") public class ProxyApplication { diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyBasicConfig.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyBasicConfig.java new file mode 100644 index 00000000..cfae6f44 --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyBasicConfig.java @@ -0,0 +1,52 @@ +package com.example.proxy.config.v2_dynamicproxy; + +import com.example.proxy.app.v1.*; +import com.example.proxy.config.v2_dynamicproxy.handler.LogTraceBasicHandler; +import com.example.proxy.trace.logtrace.LogTrace; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.lang.reflect.Proxy; + +@Configuration +public class DynamicProxyBasicConfig { + + @Bean + public OrderControllerV1 orderControllerV1(LogTrace logTrace) { + OrderControllerV1Impl orderController = new OrderControllerV1Impl(orderServiceV1(logTrace)); + + OrderControllerV1 proxy = (OrderControllerV1) Proxy.newProxyInstance( + OrderControllerV1.class.getClassLoader(), + new Class[]{OrderControllerV1.class}, + new LogTraceBasicHandler(orderController, logTrace) + ); + + return proxy; + } + + @Bean + public OrderServiceV1 orderServiceV1(LogTrace logTrace) { + OrderServiceV1Impl orderService = new OrderServiceV1Impl(orderRepositoryV1(logTrace)); + + OrderServiceV1 proxy = (OrderServiceV1) Proxy.newProxyInstance( + OrderServiceV1.class.getClassLoader(), + new Class[]{OrderServiceV1.class}, + new LogTraceBasicHandler(orderService, logTrace) + ); + + return proxy; + } + + @Bean + public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace) { + OrderRepositoryV1Impl orderRepository = new OrderRepositoryV1Impl(); + + OrderRepositoryV1 proxy = (OrderRepositoryV1) Proxy.newProxyInstance( + OrderRepositoryV1.class.getClassLoader(), + new Class[]{OrderRepositoryV1.class}, + new LogTraceBasicHandler(orderRepository, logTrace) + ); + + return proxy; + } +} diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyFilterConfig.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyFilterConfig.java new file mode 100644 index 00000000..b3c6e120 --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/DynamicProxyFilterConfig.java @@ -0,0 +1,54 @@ +package com.example.proxy.config.v2_dynamicproxy; + +import com.example.proxy.app.v1.*; +import com.example.proxy.config.v2_dynamicproxy.handler.LogTraceFilterHandler; +import com.example.proxy.trace.logtrace.LogTrace; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.lang.reflect.Proxy; + +@Configuration +public class DynamicProxyFilterConfig { + + private static final String[] PATTERNS = {"request*", "order*", "save*"}; + + @Bean + public OrderControllerV1 orderControllerV1(LogTrace logTrace) { + OrderControllerV1Impl orderController = new OrderControllerV1Impl(orderServiceV1(logTrace)); + + OrderControllerV1 proxy = (OrderControllerV1) Proxy.newProxyInstance( + OrderControllerV1.class.getClassLoader(), + new Class[]{OrderControllerV1.class}, + new LogTraceFilterHandler(orderController, logTrace, PATTERNS) + ); + + return proxy; + } + + @Bean + public OrderServiceV1 orderServiceV1(LogTrace logTrace) { + OrderServiceV1Impl orderService = new OrderServiceV1Impl(orderRepositoryV1(logTrace)); + + OrderServiceV1 proxy = (OrderServiceV1) Proxy.newProxyInstance( + OrderServiceV1.class.getClassLoader(), + new Class[]{OrderServiceV1.class}, + new LogTraceFilterHandler(orderService, logTrace, PATTERNS) + ); + + return proxy; + } + + @Bean + public OrderRepositoryV1 orderRepositoryV1(LogTrace logTrace) { + OrderRepositoryV1Impl orderRepository = new OrderRepositoryV1Impl(); + + OrderRepositoryV1 proxy = (OrderRepositoryV1) Proxy.newProxyInstance( + OrderRepositoryV1.class.getClassLoader(), + new Class[]{OrderRepositoryV1.class}, + new LogTraceFilterHandler(orderRepository, logTrace, PATTERNS) + ); + + return proxy; + } +} diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceBasicHandler.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceBasicHandler.java new file mode 100644 index 00000000..3394f9ea --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceBasicHandler.java @@ -0,0 +1,34 @@ +package com.example.proxy.config.v2_dynamicproxy.handler; + +import com.example.proxy.trace.TraceStatus; +import com.example.proxy.trace.logtrace.LogTrace; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.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); + Object result = method.invoke(target, args); + logTrace.end(status); + return result; + } catch (Exception e) { + logTrace.exception(status, e); + throw e; + } + } +} diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceFilterHandler.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceFilterHandler.java new file mode 100644 index 00000000..38f23663 --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v2_dynamicproxy/handler/LogTraceFilterHandler.java @@ -0,0 +1,45 @@ +package com.example.proxy.config.v2_dynamicproxy.handler; + +import com.example.proxy.trace.TraceStatus; +import com.example.proxy.trace.logtrace.LogTrace; +import org.springframework.util.PatternMatchUtils; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class LogTraceFilterHandler implements InvocationHandler { + + private final Object target; + private final LogTrace logTrace; + private final String[] patterns; + + public LogTraceFilterHandler(Object target, LogTrace logTrace, String[] patterns) { + this.target = target; + this.logTrace = logTrace; + this.patterns = patterns; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + //메서드 이름 필터 + String methodName = method.getName(); + + //save, request, reque*, *est , ... + if (!PatternMatchUtils.simpleMatch(patterns, methodName)) { + return method.invoke(target, args); + } + + TraceStatus status = null; + try { + String message = method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()"; + status = logTrace.begin(message); + Object result = method.invoke(target, args); + logTrace.end(status); + return result; + } catch (Exception e) { + logTrace.exception(status, e); + throw e; + } + } +}