본문 바로가기
카테고리 없음

CGLIB, JDK Dynamic Proxy - 작성중

by 흰색남자 2023. 2. 13.

자바에서는 프록시 패턴을 사용하여 객체의 접근을 제어하거나 객체에 부가적인 기능을 추가할 수 있습니다. CGLIB과 JDK Dynamic Proxy는 두 가지 프록시 기술 중 대표적인 예입니다.

CGLIB은 자바 바이트코드 조작 라이브러리로, 리플렉션을 사용하여 생성된 객체의 메서드 호출을 가로채서 부가적인 로직을 수행하는 방식의 프록시를 구현합니다. CGLIB은 상속을 사용한 프록시 구현 방식으로, 프록시 대상 클래스의 서브클래스를 동적으로 생성하여 부가 기능을 추가합니다. 이 때문에, 프록시 대상 클래스가 final 클래스인 경우에는 CGLIB을 사용할 수 없습니다. 또한, CGLIB은 바이트코드를 조작하기 때문에, 프록시 클래스 생성 시간이 JDK Dynamic Proxy에 비해 더 오래 걸릴 수 있습니다.

반면에, JDK Dynamic Proxy는 자바 표준 라이브러리로 제공되는 동적 프록시 라이브러리입니다. 자바에서는 인터페이스를 구현하는 클래스를 생성하는 것이 가능하므로, JDK Dynamic Proxy는 인터페이스를 구현하는 클래스를 생성하여 프록시 객체를 생성합니다. 이 때문에, JDK Dynamic Proxy를 사용하기 위해서는 프록시 대상 객체가 반드시 인터페이스를 구현하고 있어야 합니다. 또한, JDK Dynamic Proxy는 리플렉션을 사용하지 않고, 바이트코드를 직접 조작하지 않기 때문에, CGLIB에 비해 프록시 클래스 생성 시간이 더 빠를 수 있습니다.

따라서, CGLIB은 상속을 사용한 프록시 방식으로 프록시 대상 클래스가 final 클래스인 경우나 메서드를 final로 선언한 경우에는 사용할 수 없지만, 인터페이스를 구현하지 않은 클래스도 프록시 대상이 될 수 있습니다. 반면에, JDK Dynamic Proxy는 인터페이스를 구현한 클래스만 프록시 대상이 될 수 있지만, 프록시 클래스 생성 시간이 더 빠르고, 리플렉션을 사용하지 않기 때문에 보다 안전합니다. 따라서, 사용하는 상황에 따라 적절한 프록시 기술을 선택하는 것이 중요합니다.

 

 

 

Spring 프레임워크에서 AOP(Aspect-Oriented Programming)를 구현하는 방법 중 하나는 프록시 패턴을 사용하는 것입니다. 이 때, Spring은 CGLIB과 JDK Dynamic Proxy를 모두 지원합니다.

Spring은 우선, 인터페이스를 구현한 클래스를 대상으로 JDK Dynamic Proxy를 사용하여 프록시 객체를 생성합니다. 인터페이스를 구현하지 않은 클래스의 경우, Spring은 CGLIB을 사용하여 상속을 통해 프록시 객체를 생성합니다. 이 때, 클래스가 final인 경우에는 CGLIB을 사용할 수 없으므로, JDK Dynamic Proxy를 사용하게 됩니다.

Spring에서 AOP를 구현할 때는 대상 객체를 구현하는 클래스를 만들지 않고, 프록시 객체를 만들어 대상 객체를 대신 호출하는 방식으로 AOP를 구현합니다. 이를 위해 Spring은 JDK Dynamic Proxy와 CGLIB을 모두 사용하여 프록시 객체를 생성할 수 있도록 구현하고 있습니다.

또한, Spring은 애스팩트의 라이프사이클 관리를 위해 프록시 객체를 빈으로 등록하고, 프록시 객체가 대상 객체를 감싸는 방식으로 애스팩트를 적용합니다. 이 때, 프록시 객체는 대상 객체와 같은 빈 스코프를 가지며, 애스팩트에서 사용하는 빈이 자동으로 주입될 수 있습니다.

따라서, Spring에서는 CGLIB과 JDK Dynamic Proxy를 모두 사용하여 프록시 객체를 생성하며, 이를 이용하여 AOP를 구현합니다. Spring이 프록시 패턴을 사용하여 AOP를 구현하는 방식은 일반적으로 메서드 호출 전/후의 부가 기능을 구현하는데 많이 활용됩니다.