μ€νλ§ νλ‘μ ν©ν 리
π‘ νλ‘μ(Proxy) λ?
ν΄λΌμ΄μΈνΈκ° μ€μ μ¬μ©νλ €λ λμμΈμ μμ²μ λ°μ μ²λ¦¬νλ μν .
νλ‘μμκ² μμ²μ λ겨λ°μ μ΅μ’ μ²λ¦¬νλ μ€λΈμ νΈλ νκΉ(Target).
νκΉκ³Ό νλ‘μμΈμ§ ν΄λΌμ΄μΈνΈκ° ꡬλ³ν μ μμ΄μΌ νκΈ°μ λμ κ°μ μΈν°νμ΄μ€λ₯Ό νμ₯ν΄μΌ ν¨.
νλ‘μλ μ¬μ© λͺ©μ μ λ°λΌ 2κ°μ§λ‘ λλ¨
- λΆκ°μ μΈ κΈ°λ₯ λΆμ¬ ⇒ λ°μ½λ μ΄ν° ν¨ν΄
- μ κ·Ό μ μ΄ ⇒ νλ‘μ ν¨ν΄
νλ‘μ ν¨ν΄
κ°μ²΄ μμ±μ λΉμ© ⇒ μ΅μν, νμ μμ κΉμ§ 미루λκ² μ’μ
- νκΉμ λν μ κ·ΌκΆν μ μ΄ κ°λ₯
- μΊμ±
νλ‘μμ λ¨μ
- νλ‘μκ° λ©€λ²λ³μλ‘ νκΉ μ€λΈμ νΈ κ°μ§κΈ°μ νκΉ μ€λΈμ νΈμ μ’ μμ
- λκ°μ κΈ°λ₯ μννλ νλ‘μλΌλ μ¬λ¬ νκΉμ μ μ©νλ €λ©΄ νκΉμ κ°―μ λ§νΌ νλ‘μ μμ±ν΄μΌ νκΈ°μ μ½λ μ€λ³΅ λ°μ
- νλ‘μλ₯Ό μ¬μ©νμ§ μλ λ©μλμλ νκΉμΌλ‘ μμνλ λ©μλ μμ±ν΄μΌ ν¨
⇒ 리νλ μ κΈ°λ₯μ μ¬μ©νμ¬ νλ‘μλ₯Ό λμ μΌλ‘ μμ±ν΄μ ν΄κ²°ν΄λ³΄μ!
λ€μ΄λ΄λ―Ή νλ‘μ
μΈν°νμ΄μ€μ μ λ¬΄λ‘ ν¬κ² λΆλ₯λ¨
- μΈν°νμ΄μ€κ° μ‘΄μ¬νλ κ²½μ° ⇒ JDK λμ νλ‘μ
- μΈν°νμ΄μ€κ° μλ κ²½μ° ⇒ CGLIB
JDK λμ νλ‘μ
ꡬν ν΄λμ€κ° μλ μΈν°νμ΄μ€λ₯Ό κΈ°λ°μΌλ‘ νλ‘μ μμ±
reflectμ invocationHandlerλ₯Ό ꡬννλ©΄ λ§λ€ μ μμ
Object proxy = Proxy.newProxyInstance(ClassLoader // ν΄λμ€λ‘λ
, Class<?>[] // νκΉμ μΈν°νμ΄μ€
, InvocationHandler // νκΉμ μ λ³΄κ° ν¬ν¨λ Handler
);
Proxy κ°μ²΄ μμ±λλ κ³Όμ
- ProxyFactoryκ° νκΉμ μΈν°νμ΄μ€λ₯Ό μμν Proxy κ°μ²΄ μμ±
- proxy κ°μ²΄μ invocation Handlerλ₯Ό ν¬ν¨μμΌ νλμ κ°μ²΄λ‘ λ°ν
public class TestInvocationHandler implements InvocationHandler {
private TargetInterface target; //νκΉ μ€λΈμ νΈλ₯Ό λ©€λ² λ³μλ‘ μ μ§ν΄μΌ ν©λλ€.
public TestInvocationHandler(TargetInterface target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("νλ‘μ λΆκ°κΈ°λ₯ μμ"); //μ¬κΈ°μ λΆκ°κΈ°λ₯ λ‘μ§μ μΆκ°
Object result = method.invoke(target, args); //μ€μ νκΉ μ€λΈμ νΈλ‘ μμ²μ μμν©λλ€.
log.info("νλ‘μ λΆκ°κΈ°λ₯ μ’
λ£"); //μ¬κΈ°μ λΆκ°κΈ°λ₯ λ‘μ§μ μΆκ°
return result;
}
}
@Test
void testInvocationHandler(){
TargetInterface target = new TargetImpl();
TestInvocationHandler invocationHandler = new TestInvocationHandler(target);
//νλ‘μ μμ±
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(TargetInterface.class.getClassLoader(), new Class[]{TargetInterface.class}, invocationHandler);
//νλ‘μ μ€ν
proxy.run();
log.info("proxy = {}", proxy.getClass());
}
μλ‘μ΄ νκΉμ κΈ°μ‘΄μ νλ‘μλ₯Ό μ μ©νλ €λ©΄ μλ‘μ΄ νκΉμ μΈν°νμ΄μ€μ μΌμΉνλ νλ‘μ μΈν°νμ΄μ€λ₯Ό λ§λ€μ΄μΌ νλ λΆλΆμ InvocationHandlerλ₯Ό μ¬μ©ν΄ λμ μΌλ‘ μμ±ν΄ ν΄κ²°
CGLIB
CGLIBμ λ°μ΄νΈ μ½λλ₯Ό μ‘°μνμ¬ λμ μΌλ‘ ν΄λμ€ μμ±ν΄μ£Όλ λΌμ΄λΈλ¬λ¦¬
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MemberService.class); // νκΉ ν΄λμ€
enhancer.setCallback(MethodInterceptor); // Handler
Object proxy = enhancer.create(); // Proxy μμ±
μΈν°νμ΄μ€ μμ΄ concrete ν΄λμ€λ§ μ‘΄μ¬ν΄λ νλ‘μ μμ± κ°λ₯
CGLIBμ MethodIntercepter ν΅ν΄ ꡬνλ¨, InvocationHandlerμ λ§€μ° μ μ¬
μ±λ₯μ μΌλ‘ CGLIBμ΄ μ’μ
CGLBμ νκΉμ λν μ 보λ₯Ό μ 곡 λ°μ λ°μ΄νΈ μ½λλ₯Ό μ‘°μν΄μ Proxyλ₯Ό μμ±νκΈ° λλ¬Έμ μ΄ν νΈμΆμμλ μ‘°μλ λ°μ΄νΈ μ½λλ₯Ό μ¬μ¬μ©νμ¬ μ±λ₯μ μΌλ‘ μ’λ€.
νμ§λ§ μ΄κΈ° Springμμλ JDK λ°©μμ μ¬μ©νμμ
- net.sf.cglib.proxy.Enhancer μμ‘΄μ± μΆκ°
- default μμ±μ
- νκΉμ μμ±μ λ λ² νΈμΆ
κ°μ λ¬Έμ μ μ΄ CGLIBμ μ‘΄μ¬νκΈ° λλ¬Έμ
But, λλΆλΆ κ°μ λμ΄ νμ¬ μ€νλ§μ λ€μ΄λλ―Ή νλ‘μλ CGLIBμΌλ‘ ꡬνλ¨
μ€νλ§ AOPμ Proxy λμ
λ°νμ μλΉ(Runtime Weaving)
- Spring AOPλ νΈμΆ μμ μ IoC 컨ν
μ΄λμ μν΄ Proxy Beanμ μμ±
- μΈν°νμ΄μ€ μ 무μ λ°λΌ λ°©μ μ ν(JDK / CGLIB)
- λμ μΌλ‘ μμ±λ Proxy Beanμ νκΉμ λ©μλκ° νΈμΆλλ μμ μ λΆκ° κΈ°λ₯μ μΆκ°ν λ©μλλ₯Ό νλ¨ λ° μ£Όμ
λ€μ΄λλ―Ή νλ‘μμ λ¨μ
- μΈν°νμ΄μ€μ μ 무μ λ°λΌ JDK λμ νλ‘μ, CGLIBμΌλ‘ κ°κ° ꡬνν΄μΌ νμ
- λ€μ΄λλ―Ή νλ‘μλ₯Ό ꡬννλ InvocationHandlerμ MethodInterceptorμ νκΉ μ€λΈμ νΈκ° μ‘΄μ¬ν΄μΌ ν¨
νλ‘μ ν©ν 리λ?
λ€μ΄λλ―Ή νλ‘μμ λ¨μ λ€μ ν΄κ²°νκ³ μ μμ μΈν°νμ΄μ€μ μ 무μ λ°λΌ νλ‘μλ₯Ό μμ±ν΄μ£Όλ ν©ν 리
μ¦, κΈ°μ‘΄ λ€μ΄λλ―Ή νλ‘μμ ν©ν 리 ν¨ν΄ μ μ©
Advidsor, Advice
π‘ Advisor = Advice + Pointcut
Advice: νκΉ μ€λΈμ νΈμ μ μ©ν λΆκ°κΈ°λ₯μ λ΄μ μ€λΈμ νΈ
Pointcut: λΆκ° κΈ°λ₯μ μ μ©ν λμμΈμ§ νλ³νλ νν°λ§ λ‘μ§
νλ‘μ ν©ν 리μ λ¨μ
- νλ‘μλ₯Ό μ μ©ν μ€νλ§ Beanμ κ°―μλ§νΌ νλ‘μλ₯Ό μμ±ν΄μ BeanμΌλ‘ λ±λ‘ν΄μ£Όμ΄μΌ ν¨
- μ»΄ν¬λνΈ μ€μΊμΌλ‘ λ±λ‘λ μ€νλ§ Beanμλ μ μ© λΆκ°λ₯
λΉ νμ²λ¦¬κΈ°(Bean Post Processor)
νλ‘μ ν©ν λ¦¬κ° κ°μ§κ³ μλ λ¨μ μ ν΄κ²°νκΈ° μν΄ λΉμ λ±λ‘νκΈ° μ μ μνλλλ‘ μ‘°μν μ μλ **λΉ νμ²λ¦¬κΈ°(Bean Post Processor)**λ₯Ό μ¬μ©
μ°Έκ³
[Spring] νλ‘μμ λμμΈν¨ν΄ (tistory.com)
[Spring] λ€μ΄λ΄λ―Ή νλ‘μ(DynamicProxy) (tistory.com)`