You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
new ProxyFactory(target) : 프록시 팩토리를 생성할 때, 생성자에 프록시의 호출 대상을 함께 넘겨준다. 프록시 팩토리는 이 인스턴스 정보를 기반으로 프록시를 만들어낸다. 만약 이 인스턴스에 인터페이스가 있다면 JDK 동적 프록시를 기본으로 사용하고 인터페이스가 없고 구체 클래스만 있다면 CGLIB를 통해서 동적 프록시를 생성한다. 여기서는 target 이 new ServiceImpl() 의 인스턴스이기 때문에 ServiceInterface 인터페이스가 있다. 따라서 이 인터페이스를 기반으로 JDK 동적 프록시를 생성한다.
proxyFactory.addAdvice(new TimeAdvice()) : 프록시 팩토리를 통해서 만든 프록시가 사용할 부가
기능 로직을 설정한다. JDK 동적 프록시가 제공하는 InvocationHandler 와 CGLIB가 제공하는 MethodInterceptor 의 개념과 유사하다. 이렇게 프록시가 제공하는 부가 기능 로직을 어드바이스
(Advice )라 한다. 번역하면 조언을 해준다고 생각하면 된다.
proxyTargetClass=true : CGLIB, 구체 클래스 기반 프록시, 인터페이스 여부와 상관없음
✅정리
프록시 팩토리의 서비스 추상화 덕분에 구체적인 CGLIB, JDK 동적 프록시 기술에 의존하지 않고, 매우 편리하게동적 프록시를 생성할 수 있다.
프록시의 부가 기능 로직도 특정 기술에 종속적이지 않게 Advice 하나로 편리하게 사용할 수 있었다. 이것은 프록시 팩토리가 내부에서 JDK 동적 프록시인 경우 InvocationHandler가 Advice를 호출하도록 개발해두고, CGLIB인 경우 MethodInterceptor 가 Advice 를 호출하도록 기능을 개발해두었기 때문이다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
스프링이 지원하는 프록시
1️⃣ 프록시 팩토리 - 소개
✅ 동적 프록시의 문제점
InvocationHandler와CGLIB가 제공하는MethodInterceptor를 각각 중복으로 만들어서 관리해야 할까?🗒️ Q: 인터페이스가 있는 경우에는 JDK 동적 프록시를 적용하고, 그렇지 않은 경우에는 CGLIB를 적용하려면 어떻게 해야할까?
ProxyFactory)라는 기능을 제공한다.🗒️ Q: 두 기술을 함께 사용할 때 부가 기능을 적용하기 위해 JDK 동적 프록시가 제공하는 InvocationHandler와 CGLIB가 제공하는MethodInterceptor를 각각 중복으로 따로 만들어야 할까**?
🗒️ Q: 특정 조건에 맞을 때 프록시 로직을 적용하는 기능도 공통으로 제공되었으면?
2️⃣ 프록시 팩토리 - 예제 코드 1
➡️ Advice 만들기
Advice를 만드는 방법 여러가지가 있는데, 인터페이스를 구현하는 방법을 알아보자
➡️ MethodInterceptor - 스프링이 제공하는 코드
MethodInvocation invocationargs, 메서드 정보 등이 포함되어 있다.CGLIB의
MethodInterceptor와 이름이 같으므로 패키지 이름에 주의하자org.aopalliance.intercept패키지는 스프링 AOP 모듈(spring-aop)안에 들어있다.
MethodInterceptor는Interceptor를 상속하고Interceptor는Advice인터페이스를 상속한다.TimeAdvice
Object result = invocation.proceed()invocation.proceed()를 호출하면target클래스를 호출하고 그 결과를 받는다.target클래스의 정보가 보이지 않는다.target클래스의 정보는MethodInvocation invocation안에 모두 포함되어 있다.target정보를 파라미터로 전달받기 때문이다.ProxyFactoryTest
new ProxyFactory(target): 프록시 팩토리를 생성할 때, 생성자에 프록시의 호출 대상을 함께 넘겨준다. 프록시 팩토리는 이 인스턴스 정보를 기반으로 프록시를 만들어낸다. 만약 이 인스턴스에 인터페이스가 있다면 JDK 동적 프록시를 기본으로 사용하고 인터페이스가 없고 구체 클래스만 있다면 CGLIB를 통해서 동적 프록시를 생성한다. 여기서는target이new ServiceImpl()의 인스턴스이기 때문에ServiceInterface인터페이스가 있다. 따라서 이 인터페이스를 기반으로 JDK 동적 프록시를 생성한다.proxyFactory.addAdvice(new TimeAdvice()): 프록시 팩토리를 통해서 만든 프록시가 사용할 부가기능 로직을 설정한다. JDK 동적 프록시가 제공하는
InvocationHandler와 CGLIB가 제공하는MethodInterceptor의 개념과 유사하다. 이렇게 프록시가 제공하는 부가 기능 로직을 어드바이스(
Advice)라 한다. 번역하면 조언을 해준다고 생각하면 된다.proxyFactory.getProxy(): 프록시 객체를 생성하고 그 결과를 받는다.실행 결과
➡️ 프록시 팩토리를 통한 프록시 적용 확인
프록시 팩토리로 프록시가 잘 적용되었는지 확인하려면 다음 기능을 사용하면 된다.
모두 참이다.
인 경우 참
AopUtils.isCglibProxy(proxy) : 프록시 팩토리를 통해서 프록시가 생성되고, CGLIB 동적 프록시인 경우 참
물론
proxy.getClass()처럼 인스턴스의 클래스 정보를 직접 출력해서 확인할 수 있다.3️⃣ 프록시 팩토리 - 예제 코드 2
이번에는 구체 클래스만 있는
ConcreteService에 프록시를 적용해보자.프록시 팩토리는 인터페이스 없이 구체 클래스만 있으면 CGLIB를 사용해서 프록시를 적용한다.
나머지 코드는 기존과 같다.
실행 결과
proxyClass=class..ConcreteService$ $EnhancerBySpringCGLIB$$103821ba코드를 통해 CGLIB 프록시가 적용된 것도 확인할 수 있다.➡️ proxyTargetClass 옵션
✅ 프록시 팩토리의 기술 선택 방법
✅정리
Beta Was this translation helpful? Give feedback.
All reactions