목차
- Spring 핵심원리 고급편 - CGLIB
- Spring 핵심원리 고급편 - Dynamic Proxy 2
- Spring 핵심원리 고급편 - Dynamic Proxy 1
- Spring 핵심원리 고급편 - 리플렉션
- Spring 핵심원리 고급편 - 구체 클래스 기반 프록시 적용 2
- Spring 핵심원리 고급편 - 구체 클래스 기반 프록시
- Spring 핵심원리 고급편 - 인터페이스 프록시 1
- Spring 핵심원리 고급편 - Decorator Pattern 2
- Spring 핵심원리 고급편 - Decorator Pattern 1
- Spring 핵심원리 고급편 - Proxy 패턴 컴포넌트 스캔으로 자동 빈 등록
- Spring 핵심원리 고급편 - Proxy 패턴 인터페이스 없는 없는 구체 클래스
- Spring 핵심원리 고급편 - Proxy 패턴 인터페이스와 구체 클래스
- Spring 핵심원리 고급편 - Proxy 패턴
- Spring 핵심원리 고급편 - Strategy 패턴
- Spring 핵심원리 고급편 - Template Method 패턴
Proxy 패턴 - 실제 객체에 대한 접근 제어를 위한 디자인 패턴
기능을 수행하는 실제 (Real) 객체 대신 가상의 (Proxy) 객체 를 이용해 실제 객체 에 대한 접근을 제어 하는 디자인 패턴
프록시 패턴은 객체 지향 프로그래밍에서 사용되는 디자인 패턴 중 하나로 실제 객체와 같은 인터페이스 를 제공하는 객체를 사용하여 실제 객체에 대한 접근을 제어하는 데 사용됩니다. 즉, 프록시 객체를 사용하여 실제 객체에 대한 액세스를 제어할 수 있습니다.
프록시 객체는 실제 객체에 대한 참조를 유지하고, 클라이언트가 실제 객체에 액세스하려고 할 때 대신 실제 객체에 대한 요청을 처리합니다. 프록시 객체는 실제 객체와 같은 인터페이스를 구현하므로, 클라이언트는 프록시 객체와 실제 객체를 동일한 방식으로 사용할 수 있습니다.
프록시 패턴의 사용 사례로는 다음과 같은 것들이 있습니다.
- 원격 객체에 대한 액세스
- 원격 객체에 대한 액세스를 제어하려면, 클라이언트는 원격 객체에 직접 액세스하지 않고, 원격 객체를 대신하여 프록시 객체를 사용합니다. 이때 프록시 객체는 원격 객체에 대한 액세스를 제어하고, 원격 객체에 대한 요청을 처리합니다.
- 보안
- 프록시 객체를 사용하여 실제 객체에 대한 액세스를 제어하면, 보안상 이점이 있습니다. 프록시 객체를 사용하면, 클라이언트는 실제 객체에 직접 액세스하지 않고, 프록시 객체를 통해 액세스하므로, 실제 객체에 대한 액세스를 제어하고 보안을 유지할 수 있습니다.
- 비용
- 실제 객체에 대한 액세스 비용이 높은 경우, 프록시 객체를 사용하여 액세스 비용을 줄일 수 있습니다. 예를 들어, 원격 객체에 대한 액세스는 네트워크 비용이 들기 때문에, 원격 객체에 직접 액세스하는 것보다 프록시 객체를 사용하여 원격 객체에 대한 액세스 비용을 줄일 수 있습니다.
- 캐싱
- 프록시 객체를 사용하여 실제 객체에 대한 액세스를 캐싱할 수 있습니다. 이때 프록시 객체는 실제 객체에 대한 요청을 처리하기 전에 캐시된 결과를 반환합니다. 이를 통해, 실제 객체에 대한 액세스 비용을 줄이고, 성능을 향상시킬 수 있습니다.
Proxy 패턴의 구성 요소
Subject
- 실제 객체와 대리자 객체가 구현해야 하는 공통 인터페이스입니다. 이 인터페이스를 통해 실제 객체와 대리자 객체를 동일한 인터페이스를 갖도록 만들어줍니다.
Real Subject
- 실제 객체를 나타냅니다. 이 객체는 Proxy 객체에서 대신하는 역할을 합니다.
Proxy
- Real Subject를 대신해서 클라이언트로부터 요청을 받아 처리합니다. Real Subject에 대한 참조를 유지하고, 클라이언트에게 Real Subject와 동일한 인터페이스를 제공합니다. Proxy는 Real Subject에 대한 접근을 제어하고, 실제 객체를 생성하거나 초기화하는 역할을 합니다.
Proxy 의 주요 기능
Proxy 가 중간에 있으면 접근 제어 와 부가 기능 추가 를 수행할 수 있다.
객체의 접근 제어
- 프로그램 로직 실행시 실제 객체 대신 Proxy 객체에 로직을 대신 맡기게 된다.
권한에 따른 접근 차단
- 권한별로 실제 객체에 접근을 제한하도록 한다.
Lazy-Loading
- 실제 객체 생성을 해당 객체를 사용하기 전 시점까지 미룰 수 있는 장점이 있다.
Caching
- DB 와 같이 요청이 길어지는 값을 미리 저장해 실제 객체에 대한 접근을 줄인다.
부가 기능 추가
- 요청 값, 응답 값을 중간에 변경
- 추가 로그 남기기
Proxy Chain
- Proxy 객체가 또 다른 Proxy 객체를 부를 수 있다.
Proxy 패턴의 의존 관계
Proxy 패턴은 실제 객체와 같은 인터페이스 를 사용한다.
Client 객체 입장에서는 Server 객체 실행시 Server 객체를 실행하든 Proxy 객체를 실행하든 동일하게 실행이 되야 하기 때문에 같은 인터페이스를 이용해 구현해야 한다.
인터페이스
public interface Subject { |
실제 객체
|
Client 코드
public class ProxyPatternClient { |
비즈니스 로직 실행 및 결과
client 객체내 execute 메소드를 호출하게 되면 execute 내부 로직을 반복해서 3번 실행하는 것을 확인할 수 있다.
public class ProxyPatternTest { |
00:03:29.052 [Test worker] INFO hello.proxy.pureproxy.proxy.code.RealSubject - 실제 객체 호출 |
Proxy 패턴 적용 - 프록시 클래스 생성
Proxy 패턴을 적용해 RealSubject 객체 접근을 제어한다. 우선, RealSubject 를 만들때 사용한 Subject 인터페이스를 이용해 CacheProxy 클래스를 생성합니다.
CacheProxy 는 저장된 값이 없을 경우 RealSubject 객체 대한 접근해 데이터를 가져오고 저장된 값이 있을 경우 RealSubject 객체 접근을 생략하고 저장된 값을 반환하도록 한다.
|
비즈니스 로직 실행 및 결과
RealSubject 코드와 클라이언트 코드를 변경하지 않고 Proxy 객체를 통해 접근 제어 를 했다.
- 처음에는 실제 객체를 실행해 실행 결과를 받고 두번째 부터는 캐싱한 결과 를 받는다.
- 실제 객체 대신 Proxy 객체 주입 을 통해 런타임시
client -> cacheProxy -> realSubject
로 의존 관계가 형성된다.
|
실행 결과를 통해 Proxy 객체 CacheProxy 를 호출 후 실제 객체 RealSubject 를 호출한 것을 확인할 수 있다. 또한, 한번 호출 후 값이 캐싱되면 더 이상 실제 객체에 대한 접근이 이뤄지지 않는 것을 확인할 수 있다.
11:03:11.638 [Test worker] INFO hello.proxy.pureproxy.proxy.code.CacheProxy - 프록시 호출 |