diff --git a/spring-core/proxy/src/test/java/com/example/proxy/advisor/AdvisorTest.java b/spring-core/proxy/src/test/java/com/example/proxy/advisor/AdvisorTest.java new file mode 100644 index 00000000..1497cc46 --- /dev/null +++ b/spring-core/proxy/src/test/java/com/example/proxy/advisor/AdvisorTest.java @@ -0,0 +1,95 @@ +package com.example.proxy.advisor; + +import com.example.proxy.common.advice.TimeAdvice; +import com.example.proxy.common.service.ServiceImpl; +import com.example.proxy.common.service.ServiceInterface; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.aop.ClassFilter; +import org.springframework.aop.MethodMatcher; +import org.springframework.aop.Pointcut; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.NameMatchMethodPointcut; + +import java.lang.reflect.Method; + +@Slf4j +public class AdvisorTest { + + @Test + void advisorTest1() { + ServiceInterface target = new ServiceImpl(); + ProxyFactory proxyFactory = new ProxyFactory(target); + DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(Pointcut.TRUE, new TimeAdvice()); + proxyFactory.addAdvisor(advisor); + ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy(); + + proxy.save(); + proxy.find(); + } + + @Test + @DisplayName("직접 만든 포인트컷") + void advisorTest2() { + ServiceInterface target = new ServiceImpl(); + ProxyFactory proxyFactory = new ProxyFactory(target); + DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(new MyPointcut(), new TimeAdvice()); + proxyFactory.addAdvisor(advisor); + ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy(); + + proxy.save(); + proxy.find(); + } + + @Test + @DisplayName("스프링이 제공하는 포인트컷") + void advisorTest3() { + ServiceInterface target = new ServiceImpl(); + ProxyFactory proxyFactory = new ProxyFactory(target); + NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); + pointcut.setMappedNames("save"); + DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new TimeAdvice()); + proxyFactory.addAdvisor(advisor); + ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy(); + + proxy.save(); + proxy.find(); + } + + static class MyPointcut implements Pointcut { + @Override + public ClassFilter getClassFilter() { + return ClassFilter.TRUE; + } + + @Override + public MethodMatcher getMethodMatcher() { + return new MyMethodMatcher(); + } + } + + static class MyMethodMatcher implements MethodMatcher { + + private String matchName = "save"; + + @Override + public boolean matches(Method method, Class targetClass) { + boolean result = method.getName().equals(matchName); + log.info("포인트컷 호출 method={} targetClass={}", method.getName(), targetClass); + log.info("포인트컷 결과 result={}", result); + return result; + } + + @Override + public boolean isRuntime() { + return false; + } + + @Override + public boolean matches(Method method, Class targetClass, Object... args) { + return false; + } + } +} diff --git a/spring-core/proxy/src/test/java/com/example/proxy/advisor/MultiAdvisorTest.java b/spring-core/proxy/src/test/java/com/example/proxy/advisor/MultiAdvisorTest.java new file mode 100644 index 00000000..1f9a46bb --- /dev/null +++ b/spring-core/proxy/src/test/java/com/example/proxy/advisor/MultiAdvisorTest.java @@ -0,0 +1,74 @@ +package com.example.proxy.advisor; + +import com.example.proxy.common.advice.TimeAdvice; +import com.example.proxy.common.service.ServiceImpl; +import com.example.proxy.common.service.ServiceInterface; +import lombok.extern.slf4j.Slf4j; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.aop.Pointcut; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; + +public class MultiAdvisorTest { + + @Test + @DisplayName("여러 프록시") + void multiAdvisorTest1() { + // client -> proxy2(advisor2) -> proxy1(advisor1) -> target + + // 프록시 1 생성 + ServiceInterface target = new ServiceImpl(); + ProxyFactory proxyFactory1 = new ProxyFactory(target); + DefaultPointcutAdvisor advisor1 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice1()); + proxyFactory1.addAdvisor(advisor1); + ServiceInterface proxy1 = (ServiceInterface) proxyFactory1.getProxy(); + + // 프록시 2 생성 + ProxyFactory proxyFactory2 = new ProxyFactory(proxy1); + DefaultPointcutAdvisor advisor2 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice2()); + proxyFactory2.addAdvisor(advisor2); + ServiceInterface proxy2 = (ServiceInterface) proxyFactory2.getProxy(); + + // 실행 + proxy2.save(); + } + + @Test + @DisplayName("하나의 프록시, 여러 어드바이저") + void multiAdvisorTest2() { + // client -> proxy -> advisor2 -> advisor1 -> target + + DefaultPointcutAdvisor advisor1 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice1()); + DefaultPointcutAdvisor advisor2 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice2()); + + ServiceInterface target = new ServiceImpl(); + ProxyFactory proxyFactory = new ProxyFactory(target); + proxyFactory.addAdvisor(advisor2); + proxyFactory.addAdvisor(advisor1); + ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy(); + + // 실행 + proxy.save(); + } + + @Slf4j + static class Advice1 implements MethodInterceptor { + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + log.info("advice1 호출"); + return invocation.proceed(); + } + } + @Slf4j + static class Advice2 implements MethodInterceptor { + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + log.info("advice2 호출"); + return invocation.proceed(); + } + } + +}