[Spring] λμ νλ‘μ κΈ°μ (3) - CGLIB
2022. 6. 2. 12:59γBackend/πΏ Spring
μ§λ ν¬μ€ν μμ JDK λμ νλ‘μλ₯Ό μ μ©νκΈ° μν΄μ μΈν°νμ΄μ€κ° νμλΌκ³ νλ€. μΈν°νμ΄μ€κ° μκ³ κ΅¬μ²΄ ν΄λμ€λ§ μλ κ²½μ°, CGLIB λ°μ΄νΈμ½λ μ‘°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό ν΅ν΄ λμ νλ‘μλ₯Ό μ μ©ν μ μλ€.
CGLIB : Code Generator Library
CGLIB
: λ°μ΄νΈ μ½λλ₯Ό μ‘°μν΄μ λμ μΌλ‘ ν΄λμ€λ₯Ό μμ±νλ κΈ°μ μ μ 곡νλ λΌμ΄λΈλ¬λ¦¬- μΈν°νμ΄μ€ μμ΄
ꡬ체ν΄λμ€
λ§μΌλ‘ λμ νλ‘μλ₯Ό λ§λ€μ΄ λΌ μ μλ€. - μλλ μΈλΆ λΌμ΄λΈλ¬λ¦¬μΈλ°, μ€νλ§ νλ μμν¬ λ΄λΆ μμ€ μ½λμ ν¬ν¨λΌ μλ€.
- μ°Έκ³ λ‘ κ°λ°μκ° μ§μ CGLIB λ₯Ό μ¬μ©νλ κ²½μ°λ κ±°μ μλ€. λ€μ ν¬μ€ν μμ λ€λ£° ProxyFactory κ° CGLIB μ¬μ©μ νΈλ¦¬νκ² λμμ£ΌκΈ° λλ¬Έμ, λ무 κΉμ΄μκ² ν기보λ€λ CGLIB κ° λ¬΄μμΈμ§ λλ΅ κ°λ λ§ μ‘μΌλ©΄ λλ€.
CGLIB μμ μ½λ
λμ νλ‘μμμλ InvcationHandler λ₯Ό μ 곡νλ―, CGLIB μμλ MethodInterceptor λ₯Ό μ 곡νλ€. MethodInterceptor μΈν°νμ΄μ€λ Callback ν΄λμ€(μλλ μΈν°νμ΄μ€)λ₯Ό μμλ°κ³ μλ€λ μ λλ§ κΈ°μ΅ν΄λμ.
package org.springframework.cglib.proxy;
import java.lang.reflect.Method;
public interface MethodInterceptor extends Callback {
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}
// ConcreteService.java
@Slf4j
public class ConcreteService { // μΈν°νμ΄μ€ μλ€.
public void call() {
log.info("ConcreteService νΈμΆ");
}
}
TimeMethodInterceptor
@Slf4j
public class TimeMethodInterceptor implements MethodInterceptor {
private final Object target; // νλ‘μλ νμ νΈμΆν λμ νμΌμ΄ νμνλ€
public TimeMethodInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
log.info("TimeProxy μ€ν");
long startTime = System.currentTimeMillis();
Object result = methodProxy.invoke(target, args);
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("TimeProxy μ’
λ£ resultTime={}", resultTime);
return result;
}
}
- TimeMethodInterceptor λ MethodInterceptor μΈν°νμ΄μ€λ₯Ό ꡬνν΄μ CGLIB νλ‘μμ μ€ν λ‘μ§μ μ μνλ€.
- Object target : νλ‘μκ° νΈμΆν μ€μ λμ
- methodProxy.invoke(target, args) : μ€μ λμμ λμ μΌλ‘ νΈμΆνλ€. JDK λμ νλ‘μλ Method νμ μ νΈμΆνμ§λ§, CGLIB λ MethodProxy νμ νΈμΆμ μ±λ₯μ κΆμ₯νλ€.
CglibTest
@Slf4j
public class CglibTest {
@Test
void cglib() {
// μΈν°νμ΄μ€κ° μλ ν΄λμ€
ConcreteService target = new ConcreteService();
// CGLIB λ₯Ό λ§λλ μ½λ
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ConcreteService.class);
// ꡬ체 ν΄λμ€λ₯Ό κΈ°λ°μΌλ‘ ConcreteService λ₯Ό μμλ°μ νλ‘μλ₯Ό λ§λ€μ΄λ΄μΌνλ€.
// MethodInterceptor κ° CallBack μ μμλ°μμ μ λ
enhancer.setCallback(new TimeMethodInterceptor(target));
ConcreteService proxy = (ConcreteService) enhancer.create();
log.info("targetClass={}", target.getClass());
log.info("proxyClass={}", proxy.getClass());
proxy.call();
}
}
Enhancer
: CGLIB λ Enhancer λ₯Ό μ¬μ©ν΄ νλ‘μλ₯Ό μμ±νλ€.- νλ‘μλ₯Ό μ μ©ν ꡬ체 ν΄λμ€λ₯Ό μμλ°μ νλ‘μλ₯Ό μμ±νλ€.
setSuperClass
μ μΈμλ‘ μ΄λ€ ν΄λμ€λ₯Ό μμλ°μμ§ μ§μ νλ€. enhancer.setCallback(new TimeMethodInterceptor(target))
: νλ‘μμ μ μ©ν μ€ν λ‘μ§μ ν λΉνλ€.enhancer.create()
: ꡬ체ν΄λμ€λ₯Ό μμλ°μ ν νλ‘μλ₯Ό μμ±νλ€.
CGLIB μ μ½
- ν΄λμ€ κΈ°λ° νλ‘μλ μΈν°νμ΄μ€ κΈ°λ° νλ‘μμ λ¬λ¦¬, μμμ μ¬μ©νκΈ° λλ¬Έμ λͺκ°μ§ μ μ½μ΄ μ‘΄μ¬νλ€.
- λΆλͺ¨ ν΄λμ€μ μμ±μλ₯Ό 체ν¬ν΄μΌ νλ€.
- μμ±μκ° νμνλ€.
- ν΄λμ€μ final ν€μλκ° λΆμΌλ©΄ μμμ΄ λΆκ°λ₯νλ€. CGLIBμμλ μμΈκ° λ°μνλ€.
- λ©μλμ final ν€μλκ° λΆμΌλ©΄ ν΄λΉ λ©μλλ₯Ό μ€λ²λΌμ΄λ© ν μ μλ€. CGLIBμμλ νλ‘μ λ‘μ§μ΄ λμνμ§ μλλ€.
μ 리
- μΈν°νμ΄μ€κ° μλ κ²½μ°μ, κ·Έλ μ§ μμ κ²½μ°λ₯Ό λͺ¨λ μμ°λ₯Ό μ μλ λ°©λ²μ μμκΉ?
- λ κΈ°μ μ ν¨κ» μ¬μ©ν λ JDK λμ νλ‘μκ° μ 곡νλ InvocationHandler μ CGLIB κ° μ 곡νλ MethodInterceptor λ₯Ό κ°κ° μ€λ³΅μΌλ‘ λ§λ€μ΄ κ΄λ¦¬ν΄μΌνλ?
- μ΄λ° λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ λ€μ ν¬μ€ν μμ ProxyFactory λ₯Ό μμλ³΄κ² λ€.
μ½λ λ° μλ£ μΆμ²
'Backend > πΏ Spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Spring] Pointcut, Advise, Advisor κΈ°λ³Έ κ°λ μ μμ보μ (0) | 2022.06.03 |
---|---|
[Spring] ProxyFactory (0) | 2022.06.03 |
[Spring] λμ νλ‘μ κΈ°μ (2) - JDK DynamicProxy (0) | 2022.06.02 |
[Spring] λμ νλ‘μ κΈ°μ (1) - 리νλ μ (0) | 2022.06.02 |
[Spring] μμ λ‘ μμ보λ [ μ λ΅ ν¨ν΄ ] (0) | 2022.05.31 |