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
CGLIB : Code Generator Library
CGLIB 는 바이트 코드를 조작해 동적으로 클래스를 생성하는 기술을 제공하는 라이브러리.
이를 사용하면 인터페이스 없이 구체 클래스 만으로 동적 프록시를 만들어낼 수 있다.
원래는 외부 라이브러리인데, 스프링 프레임워크가 스프링 내부 소스 코드에 포함했다. 스프링 사용시 외부 라이브러리 추가 필요 없음.
참고로 우리가 CGLIB를 직접 사용하는 경우는 거의 없음.
나중에 설명할 스프링의 ProxyFactory 라는 것이 이 기술을 편리하게 사용하도록 도와줌.
대략적인 개념만 잡자.
예제 코드로 이해해보자.
service 인터페이스
public interface ServiceInterface {
void save();
void find();
}
구현체
@Slf4j
public class ServiceImpl implements ServiceInterface {
@Override
public void save() {
log.info("save 호출");
}
@Override
public void find() {
log.info("find 호출");
}
}
enhancer.create() : 프록시를 생성한다. 앞서 설정한 enhancer.setSuperclass(ConcreteService.class) 에서 지정한 클래스를 상속 받아서 프록시가 만
들어진다.
JDK 동적 프록시는 인터페이스를 구현(implement)해서 프록시를 만든다. CGLIB는 구체 클래스를 상속(extends) 해서 프록시를 만든다.
CGLIB가 생성한 프록시 클래스 이름
CGLIB를 통해서 생성된 클래스의 이름을 확인해보자. ConcreteService$$EnhancerByCGLIB$$25d6b0e3
CGLIB가 동적으로 생성하는 클래스 이름은 다음과 같은 규칙으로 생성된다. 대상클래스$$EnhancerByCGLIB$$임의코드
참고로 다음은 JDK Proxy가 생성한 클래스 이름이다. proxyClass=class com.sun.proxy.$Proxy1
CGLIB 제약*
클래스 기반 프록시는 상속을 사용하기 때문에 몇가지 제약이 있다.
부모 클래스의 생성자를 체크해야 한다. -> CGLIB는 자식 클래스를 동적으로 생성하기 때문에 기본 생성자가 필요하다.
클래스에 final 키워드가 붙으면 상속이 불가능하다. -> CGLIB에서는 예외가 발생한다.
메서드에 final 키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다. -> CGLIB에서는 프록시 로직이 동작하지 않는다.
참고
CGLIB를 사용하면 인터페이스가 없는 V2 애플리케이션에 동적 프록시를 적용할 수 있다. 그런데 지금 당장 적용 하기에는 몇가지 제약이 있다. V2 애플리케이션에 기본 생성자를 추가하고, 의존관계를 setter 를 사용해서 주입하면 CGLIB를 적용할 수 있다. 하지만 다음에 학습하는 ProxyFactory 를 통해서 CGLIB를 적용하면 이런 단점을 해결하고 또 더 편리하기 때문에, 애플리케이션에 CGLIB로 프록시를 적용하는 것은 조금 뒤에 알아보겠다.
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.
-
CGLIB - 소개
CGLIB : Code Generator Library
CGLIB 는 바이트 코드를 조작해 동적으로 클래스를 생성하는 기술을 제공하는 라이브러리.
이를 사용하면 인터페이스 없이 구체 클래스 만으로 동적 프록시를 만들어낼 수 있다.
원래는 외부 라이브러리인데, 스프링 프레임워크가 스프링 내부 소스 코드에 포함했다. 스프링 사용시 외부 라이브러리 추가 필요 없음.
참고로 우리가 CGLIB를 직접 사용하는 경우는 거의 없음.
나중에 설명할 스프링의
ProxyFactory라는 것이 이 기술을 편리하게 사용하도록 도와줌.대략적인 개념만 잡자.
예제 코드로 이해해보자.
service 인터페이스
구현체
인터페이스 없는 구현체
CGLIB - 예제 코드
동적 프록시 적용할 때 프록시가 실행시키는 로직
InvocationHandler제공했음.CGLIB는
MethodInterceptor제공 필요.obj: CGLIB가 적용된 객체method: 호출된 메서드args: 메서드를 호출하면서 전달된 인수proxy: 메서드 호출에 사용 (메서드 호출할 때 조금 더 빠르게 사용할 때)TimeMethodInterceptor는MethodInterceptor인터페이스를 구현해서 CGLIB 프록시의 실행 로직을 정의한다.Object target: 프록시가 호출할 실제 대상proxy.invoke(target, args): 실제 대상을 동적으로 호출한다.method를 사용해도 되지만, CGLIB는 성능상MethodProxy proxy를 사용하는 것을 권장한다.인터페이스 없는 구체 클래스로 CGLIB 를 통해 프록시 생성
Enhancer: CGLIB는Enhancer를 사용해서 프록시를 생성한다.enhancer.setSuperclass(ConcreteService.class): CGLIB는 구체 클래스를 상속 받아서 프록시를 생성할 수 있다. 어떤 구체 클래스를 상속 받을지 지정한다.
enhancer.setCallback(new TimeMethodInterceptor(target))enhancer.create(): 프록시를 생성한다. 앞서 설정한enhancer.setSuperclass(ConcreteService.class)에서 지정한 클래스를 상속 받아서 프록시가 만들어진다.
JDK 동적 프록시는 인터페이스를 구현(implement)해서 프록시를 만든다. CGLIB는 구체 클래스를 상속(extends) 해서 프록시를 만든다.
CGLIB가 생성한 프록시 클래스 이름
CGLIB를 통해서 생성된 클래스의 이름을 확인해보자.
ConcreteService$$EnhancerByCGLIB$$25d6b0e3CGLIB가 동적으로 생성하는 클래스 이름은 다음과 같은 규칙으로 생성된다.
대상클래스$$EnhancerByCGLIB$$임의코드참고로 다음은 JDK Proxy가 생성한 클래스 이름이다.
proxyClass=class com.sun.proxy.$Proxy1CGLIB 제약*
final키워드가 붙으면 상속이 불가능하다. -> CGLIB에서는 예외가 발생한다.final키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다. -> CGLIB에서는 프록시 로직이 동작하지 않는다.참고
CGLIB를 사용하면 인터페이스가 없는 V2 애플리케이션에 동적 프록시를 적용할 수 있다. 그런데 지금 당장 적용 하기에는 몇가지 제약이 있다. V2 애플리케이션에 기본 생성자를 추가하고, 의존관계를
setter를 사용해서 주입하면 CGLIB를 적용할 수 있다. 하지만 다음에 학습하는ProxyFactory를 통해서 CGLIB를 적용하면 이런 단점을 해결하고 또 더 편리하기 때문에, 애플리케이션에 CGLIB로 프록시를 적용하는 것은 조금 뒤에 알아보겠다.Beta Was this translation helpful? Give feedback.
All reactions