Category: Spring Proxy

0

Spring 핵심원리 고급편 - ProxyFactory 적용

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. 인터페이스 객체에 프록시 팩토리 적용스프링에서 제공하는 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@Configurationpublic class ProxyFactoryConfigV1 { @Bean public OrderControllerV1 orderControllerV1(LogTrace logTrace){ OrderControllerV1 orderController = new OrderControllerV1Impl(orderServiceV1(logTrace)); // OrderControllerV1 객체를 Proxy 객체로 생성한다. ProxyFactory factory = new ProxyFactory(orderController); factory.addAdvisor(getAdvisor(logTrace)); // Advisor 를 적용한다. 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)); // OrderServiceV1Impl 객체를 Proxy 객체로 생성한다. ProxyFactory factory = new ProxyFactory(orderService); factory.addAdvisor(getAdvisor(logTrace)); // Advisor 를 적용한다. 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(); // OrderRepositoryV1Impl 객체를 Proxy 객체로 생성한다. ProxyFactory factory = new ProxyFactory(orderRepository); factory.addAdvisor(getAdvisor(logTrace)); // Advisor 를 적용한다. OrderRepositoryV1 proxy = (OrderRepositoryV1) factory.getProxy(); log.info("ProxyFactory proxy = {}, target = {}", proxy.getClass(), orderRepository); return proxy; } private Advisor getAdvisor(LogTrace logTrace) { // Point Cut NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); pointcut.setMappedNames("request*", "order*", "save*"); // advice LogTraceAdvice advice = new LogTraceAdvice(logTrace); // Pointcut과 Advice 를 이용해 Advisor 객체를 만들어준다. 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@5555ffcf2021-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@5a2fa51f2021-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

0

Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. 여러 Advisor 와 함께 적용 하나의 Target 에 여러 Advisor 를 적용한다. // 여러개의 프록시 객체// client -> proxy2(advisor2) -> proxy1(advisor1) -> target// Proxy 1 생성ServiceInterface target = new ServiceImpl();ProxyFactory proxyFactory = new ProxyFactory(target);// Advisor 인터페이스의 가장 일반적인 구현체DefaultPointcutAdvisor advisor1 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice1());// ProxyFactory 에 적용할 Advisor 를 지정한다.proxyFactory.addAdvisor(advisor1);ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy();/////////////////////////////////////////////////////////////////////////////////////////////// Proxy 2 생성 (taget -> proxy 1 입력)ProxyFactory proxyFactory2 = new ProxyFactory(proxy);// Advisor 인터페이스의 가장 일반적인 구현체DefaultPointcutAdvisor advisor2 = new DefaultPointcutAdvisor(Pointcut.TRUE, new Advice2());// ProxyFactory 에 적용할 Advisor 를 지정한다.proxyFactory2.addAdvisor(advisor2);ServiceInterface proxy2 = (ServiceInterface) proxyFactory2.getProxy();proxy2.save(); 00:36:05.734 [Test worker] INFO hello.proxy.advisor.MultiAdvisorTest$Advice2 - advice2 호출00:36:05.737 [Test worker] INFO hello.proxy.advisor.MultiAdvisorTest$Advice1 - advice1 호출00:36:05.737 [Test worker] INFO hello.proxy.common.service.ServiceImpl - save 호출 하나의 프록시로 여러개의 Advisor 적용 위에서는 여러 Advisor 를 적용하기 위해서는 여러개의 프록시를 생성 해야 한다는 문제점이 있다.스프링 AOP 에서는 하나의 프록시만 생성 하고 여러개의 Advisor 를 적용 할 수 있도록 지원한다.

0

Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. save 메서드는 어드바이스 로직을 적용하지만, find 메서드에서는 어드바이스 로직을 적용하지 않도록 설정하기 Spring 에서 제공하는 Pointcut 가장 많이 사용하는 Pointcut 구현체는 AspectJExpressionPointcut 다. 클래스 설명 NameMatchMethodPointcut 메서드 이름을 기반으로 매칭한다. 내부적으로 PatternMatchUtils 을 사용한다. JdkRegexpMethodPointcut JDK 정규 표현식을 기반으로 포인트 컷을 한다. AnnotationMatchingPointcut 애노테이션으로 매칭한다. AspectJExpressionPointcut aspectJ 표현식으로 매칭한다. ServiceInterface target = new ServiceImpl();ProxyFactory proxyFactory = new ProxyFactory(target);// Spring 에서 제공하는 PointcutNameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();pointcut.setMappedNames("save");// Advisor 인터페이스의 가장 일반적인 구현체DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new TimeAdvice());// ProxyFactory 에 적용할 Advisor 를 지정한다.proxyFactory.addAdvisor(advisor);ServiceInterface proxy = (ServiceInterface) proxyFactory.getProxy();proxy.save();proxy.find(); 00:14:12.347 [Test worker] INFO hello.proxy.common.advice.TimeAdvice - TimeProxy 실행00:14:12.349 [Test worker] INFO hello.proxy.common.service.ServiceImpl - save 호출00:14:12.349 [Test worker] INFO hello.proxy.common.advice.TimeAdvice - TimeProxy 종료 resultTime = 000:14:12.351 [Test worker] INFO hello.proxy.common.service.ServiceImpl - find 호출

0

Spring 핵심원리 고급편 - Pointcut 만들기

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. Pointcut 인터페이스 Pointcut 은 getClassFilter 메서드와 getMethodMatcher 메서드를 이용해 필터링 을 진행한다.둘다 TRUE 를 반환해야 Advice 를 적용할 수 있다 getClassFilter : Class 조건으로 Filter 하는 메서드 .getMethodMatcher : Method 조건으로 Filter 하는 메서드 public interface Pointcut { // 클래스 조건으로 필터링 ClassFilter getClassFilter(); // 메서드 조건으로 필터링 MethodMatcher getMethodMatcher(); Pointcut TRUE = TruePointcut.INSTANCE;} Pointcut 적용하기 save 메서드는 Advice 로직을 적용하지만, find 메서드에서는 Advice 로직을 적용하지 않도록 설정하기

0

Spring 핵심원리 고급편 - Advisor

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. Advisor Advisor는 Spring AOP에서 Advice, Pointcut, Advisor의 개념을 쉽게 사용할 수 있도록 제공합니다. Advice 는 메소드를 실행하기 전, 후, 혹은 예외가 발생했을 때 실행되는 부가 기능을 말하며, Pointcut 은 Advice가 적용될 메소드를 선택하는 기준입니다. Advisor 는 Advice 와 Pointcut 을 결합한 것으로, 어떤 메소드에 어떤 Advice 를 적용할지를 결정합니다. PointCut (포인트 컷) 어디에 부가 기능을 적용할지 적용하지 않을지 판단하는 필터링 로직 클래스 이름과 메서드 이름을 이용해 필터링 한다. Advice (어드바이스) 프록시가 호출하는 부가 기능 Advisor (어드바이저) 단순하게 하나의 포인트 컷 과 하나의 어드바이스 를 갖고 있는 것 DefaultPointcutAdvisor

0

Spring 핵심원리 고급편 - MethodInterceptor

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. MethodInterceptor - 부가기능 구현Spring 에서는 프록시 객체에 부가기능을 적용하기 위해 MethodInterceptor 인터페이스를 제공합니다. MethodInterceptor 인터페이스 구현을 통해 프록시 객체에 적용될 부가기능을 생성할 수 있습니다. MethodInterceptor 인터페이스 내 invoke 메소드 인자 MethodInvocation 객체에는 다음 메서드를 호출하는 방법, 현재 프록시 객체 인스턴스, args, 메서드 정보등이 표함돼 있다. CGLIB 에서 제공하는 MethodInterceptor 와 이름이 비슷하므로 구현시 주의할 필요가 있습니다. package org.aopalliance.intercept;public interface MethodInterceptor extends Interceptor { Object invoke(MethodInvocation invocation) throws Throwable; }

0

Spring 핵심원리 고급편 - ProxyFactory

목차 BeanPostProcessor - 하나의 프록시에 여러개의 Advisor 적용 BeanPostProcessor Spring 핵심원리 고급편 - ProxyFactory 적용 Spring 핵심원리 고급편 - 여러 Advisor 와 함께 적용 Spring 핵심원리 고급편 - Spring 에서 제공하는 Pointcut Spring 핵심원리 고급편 - Pointcut 만들기 Spring 핵심원리 고급편 - Advisor Spring 핵심원리 고급편 - MethodInterceptor Spring 핵심원리 고급편 - ProxyFactory 참고본 포스트는 김영한의 스프링 핵심 원리 - 고급편 내용을 참고해 만들었습니다. Spring 에서의 ProxyFactory Spring 에서는 프록시 객체를 생성하기 위해 ProxyFactory 를 제공합니다. Spring에서 ProxyFactory 는 프록시 객체를 생성하는 팩토리입니다. ProxyFactory 는 인터페이스가 있을 때는 JDK 동적 프록시 를 사용해 프록시 객체를 생성하고 인터페이스가 없을 경우에는 CGLIB 를 사용해 프록시 객체를 생성합니다. Advice Advice 는 프록시에 적용하는 부가 기능 로직 이다.JDK 동적 프록시 가 제공하는 InvocationHandler 와 CGLIB 가 제공하는 MethodInterceptor 의 개념과 유사하다.