[ 이전 포스팅 요약 ]
- 요청 객체(Client)와 실제 객체(Server) 사이에 프록시 객체 도입으로 원본 코드를 수정하지 않고 의존성 주입 만으로 공통 부가 기능을 적용할 수 있게 되었다. (데코레이터 패턴 도입)
- 그리고 실제 객체마다 각각의 프록시 객체를 만들어줘야 한다는 한계를 극복하기 위해 프록시 클래스를 동적으로 생성해주는 JDK 동적 프록시 기술과 CGLIB을 사용하였다.
- JDK 동적 프록시
- 실제 객체가 인터페이스 기반일 때만 가능
- 공통 부가 기능을 InvocationHandler의 구현체에 둔다.
- Proxy.newProxyInstance 메서드에 인터페이스와 핸들러를 넘겨주며 프록시 객체를 생성
- 인터페이스 기반이기 때문에 상속 제약 없이 사용 가능하다.
- CGLIB 라이브러리
- 실제 객체가 인터페이스 없이 구체 클래스만 존재 하여도 사용 가능
- 공통 부가 기능을 MethodInterceptor의 구현체에 둔다.
- Enhancer 객체로 프록시 객체를 생성
한계
- 두 기술을 함께 사용할 때 부가 기능을 제공하기 위해서 JDK 동적 프록시의 핸들러와 CGLIB의 메서드 인터셉터를 각각 중복으로 만들어서 관리해야 할까?
- 실제 객체의 인터페이스 유무에 따라서 JDK 동적 프록시 또는 CGLIB를 자동으로 선택해주는 프록시 팩토리에 대해 알아보자.
[ 프록시 팩토리 ]

- 스프링에서 동적 프록시를 통합해서 편리하게 만들어주는 추상화된 기술
- 프록시 팩토리는 인터페이스의 유무에 따라서 JDK 동적 프록시를 사용하고, 구체 클래스만 있다면 CGLIB를 사용한다.
Advice의 도입

- 프록시 팩토리 내부에는 InvocationHandler와 MethodInterceptor가 기본적으로 존재한다.
- 그리고 이 둘은 프록시 팩토리가 주입받는 advice를 호출하여 사용한다.
- 그러므로 개발자는 공통적으로 호출되는 advice만 구현하면 된다.
- advice는 프록시에 적용하는 공통 부가 기능 로직이다.