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 fb89a253..85413bfe 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 @@ -6,6 +6,8 @@ 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.config.v3_proxyfactory.ProxyFactoryConfigV1; +import com.example.proxy.config.v3_proxyfactory.ProxyFactoryConfigV2; import com.example.proxy.trace.logtrace.LogTrace; import com.example.proxy.trace.logtrace.ThreadLocalLogTrace; import org.springframework.boot.SpringApplication; @@ -17,7 +19,9 @@ import org.springframework.context.annotation.Import; //@Import(InterfaceProxyConfig.class) //@Import(ConcreteProxyConfig.class) //@Import(DynamicProxyBasicConfig.class) -@Import(DynamicProxyFilterConfig.class) +//@Import(DynamicProxyFilterConfig.class) +//@Import(ProxyFactoryConfigV1.class) +@Import(ProxyFactoryConfigV2.class) @SpringBootApplication(scanBasePackages = "com.example.proxy.app") public class ProxyApplication { diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV1.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV1.java new file mode 100644 index 00000000..a74b0385 --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV1.java @@ -0,0 +1,57 @@ +package com.example.proxy.config.v3_proxyfactory; + +import com.example.proxy.app.v1.*; +import com.example.proxy.config.v3_proxyfactory.advice.LogTraceAdvice; +import com.example.proxy.trace.logtrace.LogTrace; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.Advisor; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.NameMatchMethodPointcut; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Configuration +public class ProxyFactoryConfigV1 { + + @Bean + public OrderControllerV1 orderControllerV1(LogTrace logTrace) { + OrderControllerV1Impl 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.getClass()); + 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.getClass()); + 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.getClass()); + 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); + } +} diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV2.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV2.java new file mode 100644 index 00000000..9270364f --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/ProxyFactoryConfigV2.java @@ -0,0 +1,59 @@ +package com.example.proxy.config.v3_proxyfactory; + +import com.example.proxy.app.v2.OrderControllerV2; +import com.example.proxy.app.v2.OrderRepositoryV2; +import com.example.proxy.app.v2.OrderServiceV2; +import com.example.proxy.config.v3_proxyfactory.advice.LogTraceAdvice; +import com.example.proxy.trace.logtrace.LogTrace; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.Advisor; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.NameMatchMethodPointcut; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@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.getClass()); + 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.getClass()); + 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.getClass()); + 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); + } +} diff --git a/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/advice/LogTraceAdvice.java b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/advice/LogTraceAdvice.java new file mode 100644 index 00000000..28738537 --- /dev/null +++ b/spring-core/proxy/src/main/java/com/example/proxy/config/v3_proxyfactory/advice/LogTraceAdvice.java @@ -0,0 +1,36 @@ +package com.example.proxy.config.v3_proxyfactory.advice; + +import com.example.proxy.trace.TraceStatus; +import com.example.proxy.trace.logtrace.LogTrace; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +import java.lang.reflect.Method; + +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 e) { + logTrace.exception(status, e); + throw e; + } + } +}