Spring Proxy에 대하여

na.ram·2025년 5월 20일

Spring

목록 보기
9/13
post-thumbnail

🔎 Proxy?

기본 개념

프록시는 클라이언트가 사용하려는 실제 대상처럼 동작하며 클라이언트의 요청을 받아 실제 대상에게 요청을 위임합니다.

  • 프록시가 실제 대상인 것처럼 위장함으로서 이를 사용하는 클라이언트는 구체 클래스를 알 필요가 없습니다.
  • 주로 실제 대상의 기능을 확장(데코레이션 패턴)하거나 실제 대상에 대한 접근 방법(프록시 패턴)을 제어하기 위해 사용합니다.
  • 메소드를 호출하면 부가 기능을 수행한 후, 실제 대상에게 메서드 호출을 위임합니다.

그러나 정적 프록시 패턴에는 대상 클래스마다 각각의 프록시 클래스를 별도로 작성해야 하므로 번거롭고, 코드의 중복이 생긴다는 단점이 있습니다.

이러한 한계를 해결하기 위해 런타임에 프록시 객체를 자동으로 생성해주는 동적 프록시가 등장했습니다. 동적 프록시를 통해 대상 클래스마다 프록시 클래스를 일일이 작성하지 않고도 다양한 객체에 공통된 방식으로 프록시를 적용할 수 있습니다.


Proxy 적용 방식

JDK 동적 프록시

JDK에서 제공하는 프록시 생성 방법으로, 인터페이스를 기반으로 프록시를 생성하는데 이 과정에서 Reflection을 이용합니다.
JDK 동적 프록시에서는 InvocationHandler(java.lang.reflect.InvocationHanlder) 인터페이스를 구현한 클래스 내부에서 타겟에게 메서드 호출을 위임하는 로직을 정의합니다.

Reflection
구체적인 클래스 타입을 알지 못해도 클래스의 변수, 메서드, 타입에 접근할 수 있도록 해주는 자바 API


Code Generation Library (CGLIB)

구체 클래스를 기반으로 프록시를 생성하는데 이 과정에서 Enhancer라는 클래스를 활용합니다.
CGLIB에서는 상속을 기반으로 타겟(실제 대상) 클래스를 확장하여 프록시 클래스를 만들며 메서드를 재정의하고, 바이트 코드를 조작해 프록시를 생성합니다.

CGLIB의 주의사항
✔️ private 접근자로 된 메서드는 상속이 불가하므로 적용되지 않습니다.
✔️ 클래스에 final 키워드가 붙으면 예외가 발생합니다
✔️ 메서드에 final 키워드가 붙으면 프록시 로직이 동작하지 않습니다.


프록시 팩토리

스프링은 프록시 팩토리를 사용해 인터페이스가 있는 경우에는 JDK 동적 프록시를, 인터페이스가 없을 때에는 CGLIB를 자동 선택합니다.


JDK 동적 프록시 Vs. CGLIB

JDK 동적 프록시는 Reflection을 활용해 메서드를 호출하기 때문에 상대적으로 성능이 떨어집니다.
그러나 CGLIB는 바이트 코드를 조작해 실제 클래스를 상속한 프록시 클래스를 직접 생성하므로 Reflection보다 빠른 성능을 낼 수 있습니다.

0개의 댓글