[ 김영한 스프링 핵심 원리 - 고급편 #6 ] 스프링이 지원하는 프록시 (3)

김수호·2023년 11월 20일
0
post-thumbnail

지난 포스팅에 이어, 이번 포스팅에서는 9) ~ 11) 까지의 내용을 정리한다.

👉 목차는 다음과 같다.

1) 프록시 팩토리 - 소개
2) 프록시 팩토리 - 예제 코드1
3) 프록시 팩토리 - 예제 코드2
4) 포인트컷, 어드바이스, 어드바이저 - 소개
5) 예제 코드1 - 어드바이저
6) 예제 코드2 - 직접 만든 포인트컷
7) 예제 코드3 - 스프링이 제공하는 포인트컷
8) 예제 코드4 - 여러 어드바이저 함께 적용
9) 프록시 팩토리 - 적용1
10) 프록시 팩토리 - 적용2
11) 정리

바로 하나씩 확인해보자.


9) 프록시 팩토리 - 적용1

지금까지 학습한 프록시 팩토리를 사용해서 애플리케이션에 프록시를 만들어보자.
먼저 인터페이스가 있는 v1 애플리케이션에 LogTrace 기능을 프록시 팩토리를 통해서 프록시를 만들어 적용해보자.

먼저 어드바이스를 만들자.

  • LogTraceAdvice 생성: src > main > java > hello > proxy > config > v3_proxyfactory > advice 패키지 내부에 LogTraceAdvice 클래스를 생성하자.
  • ProxyFactoryConfigV1 생성: src > main > java > hello > proxy > config > v3_proxyfactory 패키지 내부에 ProxyFactoryConfigV1 클래스를 생성하자.
    • 포인트컷은 NameMatchMethodPointcut 을 사용한다. 여기에는 심플 매칭 기능이 있어서 * 을 매칭할 수 있다.
      • request* , order* , save* : request 로 시작하는 메서드에 포인트컷은 true 를 반환한다. 나머지도 같다.
      • 이렇게 설정한 이유는 noLog() 메서드에는 어드바이스를 적용하지 않기 위해서다.
    • 어드바이저는 포인트컷( NameMatchMethodPointcut ), 어드바이스( LogTraceAdvice )를 가지고 있다.
    • 프록시 팩토리에 각각의 targetadvisor 를 등록해서 프록시를 생성한다. 그리고 생성된 프록시를 스프링 빈으로 등록한다.
  • ProxyApplication 수정: 다음과 같이 수정하자.
    • 프록시 팩토리를 통한 ProxyFactoryConfigV1 설정을 등록하고 실행하자.
  • 실행해보자.
    • 애플리케이션 로딩 로그
      • ProxyFactoryConfigV1 에서 남긴 로그가 출력되는 것을 확인할 수 있다.
      • V1 애플리케이션은 인터페이스가 있기 때문에 프록시 팩토리가 JDK 동적 프록시를 적용한다. 애플리케이션 로딩 로그를 통해서 JDK 동적 프록시가 적용된 것을 확인할 수 있다.
    • 실행 로그 ( http://localhost:8080/v1/request?itemId=hello )
      • 정상적으로 실행되는 것을 확인할 수 있다.

10) 프록시 팩토리 - 적용2

이번에는 인터페이스가 없고, 구체 클래스만 있는 v2 애플리케이션에 LogTrace 기능을 프록시 팩토리를 통해서 프록시를 만들어 적용해보자.

  • ProxyFactoryConfigV2 생성: src > main > java > hello > proxy > config > v3_proxyfactory 패키지 내부에 ProxyFactoryConfigV2 클래스를 생성하자.
    • (참고) ProxyFactoryConfigV1 코드를 그대로 붙여넣고 V2로 수정하자.
  • ProxyApplication 수정: 다음과 같이 수정하자.
    • 프록시 팩토리를 통한 ProxyFactoryConfigV2 설정을 등록하고 실행하자.
  • 실행해보자.
    • 애플리케이션 로딩 로그
      • V2 애플리케이션은 인터페이스가 없고 구체 클래스만 있기 때문에 프록시 팩토리가 CGLIB을 적용한다. 애플리케이션 로딩 로그를 통해서 CGLIB 프록시가 적용된 것을 확인할 수 있다.
    • 실행 로그 ( http://localhost:8080/v2/request?itemId=hello )
      • 정상적으로 실행되는 것을 확인할 수 있다.

11) 정리

프록시 팩토리 덕분에 개발자는 매우 편리하게 프록시를 생성할 수 있게 되었다. 추가로 어드바이저, 어드바이스, 포인트컷 이라는 개념 덕분에 어떤 부가 기능어디에 적용할지 명확하게 이해할 수 있었다.

남은 문제

  • 록시 팩토리와 어드바이저 같은 개념 덕분에 지금까지 고민했던 문제들은 해결되었다. 프록시도 깔끔하게 적용하고 포인트컷으로 어디에 부가 기능을 적용할지도 명확하게 정의할 수 있다. 원본 코드를 전혀 손대지 않고 프록시를 통해 부가 기능도 적용할 수 있었다. 그런데 아직 해결되지 않는 문제가 있다.

  • 문제1 - 너무 많은 설정

    • 바로 ProxyFactoryConfigV1 , ProxyFactoryConfigV2 와 같은 설정 파일이 지나치게 많다는 점이다. 예를 들어서 애플리케이션에 스프링 빈이 100개가 있다면 여기에 프록시를 통해 부가 기능을 적용하려면 100개의 동적 프록시 생성 코드를 만들어야 한다. 무수히 많은 설정 파일 때문에 설정 지옥을 경험하게 될 것이다.
    • 최근에는 스프링 빈을 등록하기 귀찮아서 컴포넌트 스캔까지 사용하는데, 이렇게 직접 등록하는 것도 모자라서, 프록시를 적용하는 코드까지 빈 생성 코드에 넣어야 한다.
  • 문제2 - 컴포넌트 스캔

    • 애플리케이션 V3처럼 컴포넌트 스캔을 사용하는 경우 지금까지 학습한 방법으로는 프록시 적용이 불가능하다. 왜냐하면 실제 객체를 컴포넌트 스캔으로 스프링 컨테이너에 스프링 빈으로 등록을 다 해버린 상태이기 때문이다.
    • 지금까지 학습한 프록시를 적용하려면, 실제 객체를 스프링 컨테이너에 빈으로 등록하는 것이 아니라 ProxyFactoryConfigV1 에서 한 것 처럼, 부가 기능이 있는 프록시를 실제 객체 대신 스프링 컨테이너에 빈으로 등록해야 한다.
  • 두 가지 문제를 한번에 해결하는 방법이 다음 섹션에서 학습할 빈 후처리기이다.


강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글