https://megamaker.tistory.com/349
[Java] 동적 프록시 (Dynamic Proxy)
이전에 살펴보았던 프록시 패턴에서는 원하는 클래스나 인터페이스마다 프록시 클래스를 만들어주어야 하는 문제가 있었다. 100곳에서 프록시를 사용한다면 프록시 클래스를 100개 만들어주어
megamaker.tistory.com
https://megamaker.tistory.com/350
[Spring] CGLIB로 프록시 직접 만들기
https://megamaker.tistory.com/349 [Java] 동적 프록시 (Dynamic Proxy)이전에 살펴보았던 프록시 패턴에서는 원하는 클래스나 인터페이스마다 프록시 클래스를 만들어주어야 하는 문제가 있었다. 100곳에서
megamaker.tistory.com
지난번에는 JDK 동적 프록시와 CGLIB 프록시를 사용해 봤는데 이때 발생한 문제 중 하나가 인터페이스가 있거나 없거나에 따라 JDK 동적 프록시와 CGLIB 프록시 중 선택해야 해서 작성해야 하는 코드가 달라진다는 것이다. 이 문제는 스프링에서 제공하는 프록시 팩토리를 이용하면 해결할 수 있다.
프록시 팩토리 사용하기
프록시 팩토리를 만들기 위해 기본적으로 내가 따로 작성해야 하는 코드는 없다. 이미 클래스가 만들어져 있기 때문에 그냥 프록시 팩토리 인스턴스만 생성하고 설정만 해주면 된다.
@Slf4j
public class MyTextAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
log.info("=================");
Object result = invocation.proceed();
log.info("=================");
return result;
}
}
공통 로직이 정의되어 있는 클래스이다. MethodInterceptor를 구현하면 되는데 여기서 주의할 점이 있다.
이전에 CGLIB에서 사용했던 MethodInterceptor와는 다르다는 점이다. 지금 사용하려고 하는 것은 org.aopalliance.intercept.MethodInterceptor 이고, CGLIB에서 사용한 것은 org.springframework.cglib.proxy.MethodInterceptor 이다. 이 부분을 조심해야 한다.
그리고 MethodInterceptor가 상속하고 있는 클래스를 거슬러 올라가보면 Advice가 있는데 이것은 Adivisor가 가지고 있는 요소 중 하나이다. Advisor는 Pointcut과 Advice를 가지고 있는데 Pointcut은 어떤 생성과 실행에서 필터 역할을 해서 어느 때 프록시를 적용할지 설정할 수 있도록 하고, Advice는 위와 같은 공통 로직이 들어있는 부분이다.
이번부터 이전과 다른 점은 공통 로직이 있는 클래스에 실제 비즈니스 로직이 담겨있는 변수를 가지고 있지 않다는 점이다. 그 이유는 밑의 프록시 팩토리를 만들 때 이미 해당 인스턴스를 넣어주는 처리를 하기 때문이다.
@Test
void proxyFactoryCGLIBTest() {
MyText target = new MyText();
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addAdvice(new MyTextAdvice());
MyText proxy = (MyText) proxyFactory.getProxy();
proxy.print("안녕하세요 ^^b");
log.info("proxy={}", proxy.getClass());
Assertions.assertThat(AopUtils.isCglibProxy(proxy)).isTrue();
}

프록시 팩토리를 만들고 실제 비즈니스 로직이 담긴 인스턴스를 넘겨주고 위에서 정의했던 Advice를 하나 만들어 넘겨주면 된다.
실행 결과를 보면 프록시는 자동으로 CGLIB 프록시로 생성된 것을 알 수 있다. AopUtils 클래스의 is~() 메서드를 사용하면 어떤 프록시인지 확인할 수 있다.
@Test
void proxyFactoryJDKDynamicTest() {
MyTextInterface target = new MyTextImpl();
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addAdvice(new MyTextAdvice());
MyTextInterface proxy = (MyTextInterface) proxyFactory.getProxy();
proxy.print("안녕하세요 ^^b");
log.info("proxy={}", proxy.getClass());
Assertions.assertThat(AopUtils.isJdkDynamicProxy(proxy)).isTrue();
}

이번에는 인터페이스가 있는 로직을 수행하는데 결과를 보면 JDK 동적 프록시가 만들어진 것을 알 수 있다. 그런데 여기서 JDK 동적 프록시가 아닌 CGLIB으로 생성되도록 하는 방법이 있는데 proxyFactory에서 setProxyTargetClass(true) 를 작성해 주면 된다. 그럼 JDK 동적 프록시가 아닌 CGLIB 프록시로 생성된다.
'공부 > Spring' 카테고리의 다른 글
| [Spring] 빈 후처리기 (BeanPostProcessor) (0) | 2024.07.27 |
|---|---|
| [Spring] Advisor 이용해서 Proxy Factory 사용하기 (0) | 2024.07.26 |
| [Spring] CGLIB로 프록시 직접 만들기 (0) | 2024.07.24 |
| [Spring] MapStruct로 이미지 경로 수정하기 + Null Pointer Exception 해결하기 (0) | 2024.06.16 |
| [Spring] Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' is not supported] (0) | 2024.05.24 |