[Spring의 디자인 패턴] 3. 프록시 패턴

namkun·2023년 6월 12일
0

T-I-L

목록 보기
16/20

프록시

  • 프록시는 '대리자'라는 의미로 실제 대상인 것 처럼 client의 요청을 대신 받아주는 것을 말한다.
    이를 통해서 client는 구체 클래스에 대해 알 필요가 없어진다.
  • 프록시의 조건은 client가 타켓인지 프록시인지 몰라야 한다.
    즉, 타겟과 프록시는 같은 인터페이스를 확장해야 한다.

프록시 패턴

  • 프록시 패턴은 타겟에 대한 접근을 제어하고자 프록시를 사용하는 패턴을 말한다.
  • 프록시를 이용하면 타켓 오브젝트에 대한 레퍼런스가 미리 필요할 때, 객체를 미리 생성해서 넘겨주지 않고 프록시를 넘겨준 다음 프록시의 메서드를 이용해서 실제로 사용될 때 생성할 수 있다.
    이를 통해서 객체 생성 비용의 소모를 최대한 뒤로 미룰 수 있는 것이다.
  • 특정 상황에서 타겟에 대한 접근 권한을 제어할 수 있다.
    특정 상황에서 핵심로직을 호출하기 전에 예외를 호출하는 식으로 제어한다.
  • 캐싱이 가능하다. 타겟으로부터 받은 응답이 메모리에 존재하면 프록시는 타겟으로 요청을 보내지 않고 기존 응답의 데이터로 클라이언트에게 리턴해주면 된다.

장점

  • 사이즈가 큰 객체가 로딩되기전에 참조를 할 수 있다.
  • 실제 객체의 public, protected 메서드를 숨기고 인터페이스를 통해 노출이 가능하다.
  • 원 객체의 접근에 대해서 사전 처리를 할 수 있다.

단점

  • 빈번한 객체 생성이 필요한 상황에서는 매번 프록시를 거쳐야해서 성능이 저하될 우려가 있다.
  • 프록시 안에 실제 객체 생성을 위해 스레드가 생성되고 동기화가 구현되어야 하는 경우, 성능이 저하되고 로직이 난해해 질 수 있다.

Spring 에서의 Proxy 패턴

AOP

AOP는 핵심 모듈 사이에 필요한 기능을 삽입해서 적절한 타이밍에 호출되도록 도와주는 기능이다.

Spring은 사용자의 특정 호출 시점에 IoC 컨테이너에 의해 AOP를 할 수 있는 proxy bean을 생성하고, 이 proxy bean은 타겟의 메서드가 호출되는 시점에 부가 가능을 추가할 메서드를 자체적으로 판단하고 가로채어 기능을 주입한다.

Spring에서는 Runtime Weaving을 할 수 있도록 상황에 따라서 JDK Dynamic Proxy, CGLib Proxy 방식을 통해서 proxy bean을 생성해주는데, 이때 어떤 것을 사용할지를 결정하는 방법은 타켓이 인터페이스가 있냐 없냐 이다.

인터페이스가 있다면 JDK Dynamic Proxy, 없다면 CGLib Proxy 이다.

JDK Dynamic Proxy

  • Java의 리플렉션 패키지안에 존재하는 Proxy라는 Class를 통해서 생성하는 방식이다.
  • 타겟의 인터페이스를 기준으로 proxy를 생성한다.
  • 내부적으로 주입된 타겟에 대한 검증코드가 존재하여, 실제로 주입된 것이 원하는 타겟의 메서드인지 확인한다.

CGLib (code generator library)

  • Class의 Byte Code를 조작해서 Proxy 객체를 생성한다.
  • CGLib를 사용해서 인터페이스가 아닌 타겟의 class에 대해서도 Proxy를 생성, 이 때 Enhancer이라는 Class로 Proxy를 생성한다.
  • CGLib 는 제공받은 타겟 클래스에 대한 Byte Code를 조작해서 생성한다. 즉, 해당 타겟에 대한 정보를 받기에 성능적으로는 JDK Dynamic Proxy보다 좋다.
  • 상속을 통해서 Proxy를 구현하기에 final class 인 경우 Proxy를 생성할 수 없다.

이전에는 CGLib가 성능이 좋더라도 한계점이 있어 default로 JDK Dynamic Proxy를 사용하였으나,
Spring 4 버전부터는 CGLib가 갖던 한계점들이 대부분 개선이 되어, Spring boot2 에서부터는 CGLib Proxy가 default가 되었다.

물론, 그렇다고 해서 JDK Dynamic Proxy가 사용되지 않는 것은 아니다. 그러니 알고 있도록 하자.

@Transactional

실제 객체 대신 프록시를 사용함으로써, Bean에 대한 접근을 제어하고 이를 통해서 트랜잭션 일관성을 보장한다.

트랜잭션 일관성 : 트랜잭션이 성공적으로 수행된 후에도 데이터베이스가 일관성 있는 상태를 유지해야 한다.

참조

profile
개발하는 중국학과 사람

0개의 댓글