Spring

스프링 프레임워크 CGLIB, Dynamic Proxy

KimGeonWoo 2023. 8. 29. 15:44

스프링에는 3가지의 특징인 IoC/DI, AOP, PSA가 있습니다.

IoC/DI는 어플리케이션에서 단위에서 개발자가 객체에 대한 생성과 제어를 담당한 것을 프레임워크단위에서 생성, 제어하는 기능이라 볼 수 있습니다.

PSA는 추상화된 인터페이스를 사용하여 OCP원칙을 지켜 유지보수성, 확장성, 낮은 응집도를 지향하게 도와줍니다.

AOP에서는 중복된 코드 핵심코드와 부가기능 등을 모듈화 하여 코드의 간결성 및 재사용성을 높이며 유지보수성을 향상시킵니다.

그렇다면 스프링 프레임워크에서 AOP의 특징을 활용하여 객체를 어떻게 관리하는지에 대해 CGlib와 Dynamic Proxy의 개념과 특징, 차이점 들에 대해 알아보겠습니다.

 

Proxy (프록시)

정의

Proxy란 사전적인 의미로는 대리인을 뜻하며, 개발자 관점으로는 클라이언트로부터 실제 대상인 타깃을 대신하여 요청을 받는 대리인, 대리자 역할을 하는. 즉, 접근 제어 또는 부가기능을 담당하는 오브젝트입니다.

※Target : 프록시를 통해 최종적으로 요청을 위임받아 처리하는 실제 오브젝트

 

특징

  • OCP원칙을 지향하여 코드의 재사용성과 낮은 응집도를 통한 확장 및 유지보수성을 향상시킨다.
  • Aspect를 프록시로 분리하여 중복되는 코드들을 제거하여 간결성을 유지시킨다.

프록시의 정의와 특징들을 간단하게 알아보았습니다.

스프링의 특징 중 하나인 AOP는 프록시를 기반으로 하며, Aspect를 접근 및 부가기능으로 사용하기위해 설계되었습니다.

또한 프록시의 메커니즘은 JDK Dynamic Proxy 또는 CGLIB를 사용하여 주어진 대상 객체에 대한 프록시를 생성합니다.

 

그렇다면, 스프링은 런타임시에 JDK Dynamic Proxy와 CGLIB가 Aspect를 어떻게 관리하는지에 대해 알아보겠습니다.

 

Dynamic Proxy

스프링 프레임워크의 Dynamic Proxy는 프록시 팩토리에 의해 런타임환경에서 동적으로 연결해주는 오브젝트 입니다.

내부 구조적으로는 다이나믹 프록시가 호출이되면, 클라이언트의 요청을 리플렉션 정보로 변환하여 InvocationHandler 

인터페이스의 invoke() 메서드를 통하여 연결이 되는구조입니다.

리플렉션(Reflection) : 자바 코드 자체를 추상화하여 접근하도록 만드는 것.

 

Dynamic Proxy의 특징으로는 프록시할 대상 객체가 하나 이상의 인터페이스를 구현하는 경우에 JDK Dynamic Proxy 형태로 ASP가 프록시 됩니다.

이로인해 JDK Dynamic Proxy 기반으로 객체를 관리하기 위해서는 모든 타깃 클래스들이 하나 이상의 인터페이스를 구현해야하는 강제성이 있습니다.

 

JDK Dynamic Proxy의 장단점

  • Dynamic Proxy는 자바의 STL에 내장되어있어 별도의 라이브러리 의존성이 없다.
  • 타깃 클래스가 인터페이스의 구현을 강제하게 된다.
  • Dynamic Proxy에서 자바코드가 추가되어도 기존의 코드에는 변경성이 없다.(OCP)
  • 어떤 종류의 인터페이스를 구현한 타깃이든 상관없이 적용할 수 있다.

 

CGlib Proxy

CGlib(Code Generation Library)는 동적으로 클래스를 생성하고 확장하기 위한 라이브러리 입니다.

해당 방법으로 객체를 관리하는 경우에는 인터페이스를 확장한 경우가 아닌 클래스의 확장을 통하여 프록시를 생성하는 경우에 사용됩니다.

즉, CGLib의 방식은 클래스의 상속을 통하여 Proxy할 메서드를 오버라이딩을 사용하여 생성됩니다.

 

CGLib의 장단점

  • 바이트 코드로 변환하여 사용하기 때문에 Dynamic Proxy보다 처리속도가 빠르다.
  • final 클래스나 final 메서드를 포함하는 경우에는 CGLib를 사용할 수 없다.

정리

AOP는 프록시를 기반으로 구성되어있다.

프록시는 스프링 프레임워크에서 런타임 환경에서 객체들을 동적으로 요청,응답을 하기위해 사용한다.

AOP기반에서 객체를 관리하는 방법에는 두가지 방법이있으며 각각의 차이점들이 있다.

  JDK Dynamic Proxy CGLib Proxy
타깃 조건 하나 이상의 인터페이스를 확장한 타깃 클래스 인터페이스가 아닌 부모 클래스를 상속한 클래스
성능 CGLib보다 조금 느리다. Dynamic Proxy보다 조금 빠르다.
Final 최종 클래스와 최종 메서드는 프록시가 될 수 없다. (Final 클래스, 메서드 X)
사용 조건 타깃 클래스가 하나 이상의 인터페이스를 구현해야 한다 타깃 클래스가 인터페이스를 구현하지 않아야 한다
AOP JoinPoint InvocationHandler Interface MethodInterceptor interface
AOP Advice Invoke() 메서드 Interceptor() 메서드

 

느낀점

스프링 프레임워크를 배우면서 처음으로 포스팅을 해보았습니다.

지금까지는 인텔리제이 IDE를 사용하여 CS학습시에도 추가적으로 예시 코드들을 사용했었는데,

스프링을 배우면서 아직 이론을 먼저 자세히 알고싶어 예시코드를 직접 작성하지 않다보니 책에서 배운 내용만으로는 직관적으로 이해가 안되는 부분들이 많았습니다.

개발블로그에 글을 작성하기위해 다른 학습 자료들을 알아보았으며, 그로인해 AOP가 어떻게 동작하는지, 그리고 동작하는 방법이 어떤것인지에 대해 더 상세하게 이해할 수 있었습니다.

이번 포스팅을 통해 AOP의 내부적으로 실행되는 방식에 대해 알 수 있었으며, 다음 스프링 관련 작성에서는 Spring AOP와 AspectJ에 대해 알아보겠습니다.

 


https://www.tutorialspoint.com/difference-between-jdk-dynamic-proxy-and-cglib-proxy-in-spring

https://docs.spring.io/spring-framework/docs/2.0.x/reference/aop.html#aop-understanding-aop-proxies 

https://huisam.tistory.com/entry/springAOP

토비의 스프링 3.1 Vol.1 - 6장 AOP