[Spring] 프록시 자동 생성 : 프록시 팩토리

전현준·2024년 9월 3일
0

Spring

목록 보기
15/17

개요


인프런 강의 [스프링 핵심 원리 - 고급편] 강의를 기반으로 작성한 글 입니다.



이전 시간에

저번시간에 [Spring] 동적 프록시 기술을 공부했었다.

JDK 동적 프록시구체 클래스 기반 프록시(CGLIB)를 작성했었다.

사실 CGLIB는 작성하지 않았다.

하지만 문제점이 무엇인가? 두개가 구현 해야 할 인터페이스가 다르다는 것이다.

JDK 동적 프록시CGLIB
구현InvocationHandlerMethodInterceptor

부가 기능을 넣을 인터페이스가 둘이 다르다.


또한, 실제 로직이 담겨있는 클래스의 인스턴스를 미리 생성하고, 그 인스턴스를 미리 넘겨주어야 한다.

실제 기존의 생성자를 보면 target(실제 인스턴스)를 넘겨주는 모습을 보고있다.

이렇게 번거로운 과정을 거쳐야 한다. 그리고 생각보다 복잡하다.

Handler만들고, 클래스로더를 정하고, 클래스 지정해서 할당해주어야 proxy가 생성된다.

또한 CGLIB의 방식은 또 다르다.

🤔 아 그러면, 두 방식이 합쳐져서는 없으려나?

💡 있다!! ProxyFactory를 사용하면 된다.



프록시 팩토리

프록시 팩토리JDK 동적 프록시CGLIB를 둘 다 사용할 수 있다.

다시 말하면, 기존의 각기 다른 인터페이스를 구현해서 부가 기능을 생성했던 것과는 달리,
이제는 프록시 팩토리 방식으로 한번에 구현할 수 있다는 것이다.

일단 프록시 팩토리의 부가기능은 Advice에 구현하면 된다.


Advice

우리가 기존에 작성해둔 Handler와 동일한 기능을 한다.

부가 기능을 작성하기 위한 클래스이며, MethodInterceptor 인터페이스를 구현하면 된다.

생각보다 다른 점이 없다. 하지만 달라진 점은 invoke 메소드를 오버라이딩하고,
invocation.proceed()를 통해서 proxy를 꺼내올 수 있다.

달라진 점은 그정도 일듯 하다.


여기서 몇가지 질문들이 있을 것 같다.

🧐[질문 1]CGLIBMethodInterceptor 인터페이스를 구현하는데 같은거구나!

❌ 사실이 아니다. 이름은 같지만 패키지명이 다르다.

  • ProxyFactory : Advice
    org.aopalliance.intercept 이다.

  • CGLIB : MethodInterceptor
    org.springframework.cglib.proxy 이다.

    둘의 패키지를 잘 구분하자.

🧐[질문 2] 근데 Advice를 인터페이스를 구현한다면서요?

✅️ 그렇다.MethodIntercepterInterceptor를 상속하고 있었고,InterceptorAdvice를 상속하고 있었다.
결국 MethodIntercepterAdvice를 구현하는거나 마찬가지이다.


Pointcut, Advisor

기존에 프록시를 설정할 때 메소드명으로 필터를 적용해서 프록시를 적용할 메소드만 구분했었다.

프록시 팩토리는 만들어서 지정이 가능하다. 그것을 우리는 Pointcut이라고 부른다.

용어 정리

  • PointCut : 메소드명이나 클래스명으로 필터를 지정할 수 있는 방법
  • Advice : 부가 기능을 저장할 프록시 로직
  • Advisor : 하나의 포인트컷과 하나의 어드바이스의 세트

Advisor는 Pointcut과 Advice를 세트로 가지어, 프록시 팩토리에 저장할 수 있는 개념이다.

사실 모든 프록시 팩토리는 Advisor 하나씩은 가지고 있다.

코드로 살펴보면, Advisor를 지정할 때, 포인트컷과 Advice를 지정하여 addAdvisor로 등록하는 모습이다.

여러개의 Advisor도 한번에 적용이 가능하다!

직접 Pointcut을 만들 수도 있는데... 굳이...?

스프링에서도 Pointcut을 제공한다.

NameMatchMethodPointcut 메소드 이름도 참 직관적이다.
= 메소드 이름으로 매치하는 포인트컷!

여기서는 save라는 메소드만 proxy를 실행하는 포인트 컷이다.


여러 Advisor 적용하기

하나의 기능에 여러 proxy(부가 기능)를 붙이고 싶을 수 있다.

그렇다면 여러 advisor를 붙일 수 있다!!

📌 advisor : 하나의 pointcut + 하나의 advice 📌

advisor는 여러개의 advice를 붙일 수 없기 때문에 하나의 advice를 여러 advisor로 붙이는 것이다.


순서에 주의하자.

위와 같은 코드를 실행시키면 advisor2 → advisor1 → Service(실제 기능)이 실행된다.

profile
백엔드 개발자 전현준입니다.

0개의 댓글

관련 채용 정보