https://megamaker.tistory.com/349
[Java] 동적 프록시 (Dynamic Proxy)
이전에 살펴보았던 프록시 패턴에서는 원하는 클래스나 인터페이스마다 프록시 클래스를 만들어주어야 하는 문제가 있었다. 100곳에서 프록시를 사용한다면 프록시 클래스를 100개 만들어주어
megamaker.tistory.com
ㄴ 이전 게시글
지난번에는 인터페이스가 있는 기능을 JDK 동적 프록시를 이용해서 프록시를 직접 구현해봤는데 이번에는 인터페이스가 없는 그냥 클래스를 프록시로 만들어 구현해보았다. CGLIB은 원래 외부 라이브러리였다고 한다. 그런데 스프링 프레임워크에 포함되어 따로 라이브러리를 포함시키는 과정없이 사용할 수 있다.
CGLIB 프록시 사용하기
이번에도 저번과 같이 출력을 원하는 문자열을 ========로 감싸서 출력할 계획이다.
@Slf4j
public class MyText {
public void print(String text) {
log.info(text);
}
}
입력을 받아 출력하는 실질적인 비즈니스 로직을 맡은 클래스이다.
@Slf4j
public class MyTextInterceptor implements MethodInterceptor {
private final Object target;
public MyTextInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
log.info("=================");
Object result = method.invoke(target, objects);
log.info("=================");
return result;
}
}
부가적이고 공통적인 역할을 맡은 클래스이다. CGLIB을 이용하려면 org.springframework.cglib.proxy.MethodInterceptor 인터페이스를 구현해야 한다. 내부에 역시 비즈니스 로직을 포함하고 있는 객체가 있고, intercept() 메서드 안에는 공통 로직이 위치해 있다.
public class WrapTest {
@Test
void wrapTextTest() {
MyText target = new MyText();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyText.class);
enhancer.setCallback(new MyTextInterceptor(target));
MyText proxy = (MyText) enhancer.create();
proxy.print("안녕하세요 ^^b");
}
}

CGLIB로 프록시를 생성할 때는 Enhancer 클래스를 이용한다. 인터페이스가 아닌 그냥 클래스를 이용하는 경우는 상속을 이용하기 때문에 부모 클래스 역할을 할 비즈니스 로직 코드가 있는 클래스를 설정하고, 공통 로직을 수행할 콜백 클래스도 설정한다. 내부에 실제 수행될 인스턴스가 있어야 하므로 target을 설정해주었다.
이렇게 인터페이스가 없는 클래스도 CGLIB로 프록시를 만들 수 있다는 것을 알아보았다. 이제 각 클래스마다 새로운 프록시 클래스를 만들지 않아도 된다는 장점이 생겼지만 해결되지 않은 문제도 있다. 인터페이스, 클래스 별 JDK 동적 프록시나 CGLIB 동적 프록시를 나누어서 구현해야 한다는 점, 프록시 생성 코드를 필요한 만큼 계속 작성해주어야 한다는 점, 어노테이션을 사용하여 컴포넌트 스캔으로 스프링 빈으로 등록한 객체에서는 사용이 어렵다는 점이다. 이 문제는 스프링의 프록시 팩토리와 빈 후처리기로 해결할 수 있는데 이건 다음에 알아보도록 하겠다.
'공부 > Spring' 카테고리의 다른 글
| [Spring] Advisor 이용해서 Proxy Factory 사용하기 (0) | 2024.07.26 |
|---|---|
| [Spring] 프록시 팩토리(Proxy Factory) 사용하기 (0) | 2024.07.25 |
| [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 |
| [Spring Web] Spring MVC 컨트롤러 요청/응답 가능한 여러가지 방법 (0) | 2024.03.21 |