AOP 실습 중 JDK 동적 프록시를 이용하여 test를 진행하는 부분이 있었다. JDK 동적 프록시가 뭔지 모르고, CGLIB 등등 프록시라는 말은 자주 써왔는데 막상 해보려니 잘 안돼서 자바와 스프링에서 프록시를 어떻게 구현하고 사용해야하는지 정리하게 됐다.
프록시(Proxy)는 대리자라는 뜻이다. 클라이언트가 서버에 직접 요청을 보내는 것이 아니라 중간에 프록시를 호출하는 것을 말한다.
단, 클라이언트는 프록시로 보낸 것인지 서버로 보낸건지 몰라야 한다. 그저 요청을 보낼 뿐이다.
중간 객체를 통해서 우리는 여러가지 일을 할 수 있는데 크게 2가지 분류로 나눈다면 접근 제어와 부가기능 추가로 나눌 수 있다.
1. 접근제어
- 권한에 따른 접근 차단
- 캐싱
- 지연 로딩
2. 부가 기능 추가
- 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행한다.
예시1) 요청 값이나, 응답 값을 중간에 변형
예시2) 실행 시간을 측정해 로그를 남긴다.
GOF 디자인 패턴에는 프록시의 의도에 따라 프록시 패턴과 데코레이터 패턴으로 구분지을 수 있다고 말한다.
클라이언트가 호출을 할 때 CacheProxy에 먼저 접근하여 캐시 값이 있는지 확인한 뒤 실제 객체의 함수를 호출한다. 로그 기록에는 아래처럼 남게 된다.
구현방법은 거의 동일하다. 다만 역할에 따라서 구분하기 때문에 데코레이터의 역할은 말 그대로 값을 꾸며주는 역할을 한다.
GOF의 디자인패턴에서 정의하는 프록시 패턴이 가장 기본적인 프록시 형태다. 인터페이스가 존재한다면 위 두 방법처럼 구현하면 되지만, 인터페이스가 존재하지 않는다면 상속을 통해 풀어내야한다.
가령 실행 시간 로그를 출력하는 프록시를 만든다 했을 때, 부모 클래스에 의존적이므로 프록시 대상이 되는 객체마다 프록시 객체를 만들어줘야 한다. 따라서 100개의 클래스에 실행시간을 측정하려면 100개의 클래스를 만들어야 한다는 단점이 있다.
이 문제를 해결하기위해 동적 프록시가 나왔다.