CGLIB

slee2·2022년 3월 14일
0
post-custom-banner

CGLIB: Code Generator Library
CGLIB는 바이트코드를 조작해서 동적으로 클래스를 생성하는 기술을 제공하는 라이브러리이다.
CGLIB를 사용하면 클래스여도 동적 프록시를 만들어낼 수 있다.

참고로 우리가 CGLIB를 직접 사용하는 경우는 거의 없다.
나중에 ProxyFactory라는 것이 최종본일 예정이기 때문에 빌드업의 과정일뿐

예제 코드

ServiceInterface

ServiceImpl

ConcreteService

JDK 동적 프록시를 위해 InvocationHandler를 사용했듯이,
CGLIB는 MethodInterceptor를 사용해야한다.

obj: CGLIB가 적용된 객체
method: 호출된 메서드
args: 메서드를 호출하면서 전달된 인수
proxy: 메서드 호출에 사용

이전과 거의 같은 코드이다.
참고로 method를 사용해도 되지만 성능은 methodProxy가 더 좋다고 한다.

이렇게 인터페이스 없는 구체 클래스를 CGLIB를 사용해서 실행한 것을 확인할 수 있다.

Enhander: CGLIB는 Enhancer를 사용해서 프록시를 생성한다.
enhancer.setSuperclass(ConcreteService.class): CGLIB는 구체 클래스를 상속 받아서 프록시를 생성할 수 있다. 어떤 구체 클래스를 상속 받을지 지정한다.
enhancer.setCallback(new TimeMethodInterceptor(target))

  • 프록시에 적용할 실행 로직을 할당한다.
    enhancer.create(): 프록시를 생성한다. 앞서 설정한 enhancer.setSuperclass(ConcreteService.class)에서 지정할 클래스를 상속 받아서 프록시가 만들어진다.

제약
클래스 기반 프록시는 상속을 사용하기 때문에 몇가지 제약이 있다.

  • 부모 클래스의 생성자를 체크해야 한다.
    • CGLIB는 자식 클래스를 동적으로 생성하기 때문에 기본 생성자가 필요하다.
  • 클래스에 final 키워드가 붙으면 상속이 불가능하다. -> CGLIB에서는 예외가 발생
  • 메서드에 final 키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다.

이걸로 v2에 적용할 수 있다. 그런데 기본 생성자를 추가하고, 의존관계를 setter적용하면 CGLIB 사용할 수는 있는데,
뒤에서 나올 ProxyFactory를 통해 CGLIB의 단점을 알아보고 그때 적용해보기로.

post-custom-banner

0개의 댓글