
인프런 강의 [스프링 핵심 원리 - 고급편]을 수강하고 정리한 내용을 바탕으로 작성하였습니다.
프록시는 다양한 역할을 수행할 수 있다.
접근 제어부가 기능 추가프록시 체인 (예시 : client -> proxy1 -> proxy2 -> server)🤔그렇다면 아무 객체나 프록시가 될 수 있을까?
아니다.
객체가 프록시로 거듭나려면, 클라이너트는 서버에게 요청을 한 것인지 프록시에게 요청을 한 것인지 몰라야 한다. 달리 말하면 클라이언트가 요청하는 대상을 서버 객체에서 프록시 객체로 변경해도 클라이언트는 몰라야 한다는 것이다.
DI를 사용하여 런타임에 client는 proxy를 의존하고, proxy는 실제 객체를 의존하도록 프록시를 적용할 수 있다.
GOF 디자인 패턴에서는 의도(intent)에 따라서 프록시 패턴과 데코레이터 패턴으로 구분한다.
프록시 패턴: 접근 제어가 목적데코레이터 패턴: 새로운 기능 추가가 목적

위와 같은 Subject 인터페이스를 이용하여 실제 객체(RealSubject)와 프록시(CacheProxy)를 구현하였다.

⬆️ RealSubject.java

⬆️ CacheProxy.java

클라이언트는 단순히 Subject를 의존한다.

클라이언트는 Subject를 의존할 뿐이지만 프록시와 실제 객체 모두 Subject 인터페이스의 구현체이기 때문에 중간에 프록시를 적용할 수 있게 되는 것이다.


위와 같은 간단한 Component 인터페이스를 이용하여 실제 컴포넌트(RealComponent)와 데코레이터(TimeDecorator, MessageDecorator)를 구현하였다.

클라이언트 코드는 단순히 Component를 의존한다.
이처럼 클라이언트는 Component를 의존할 뿐이지만 데코레이터와 실제 객체 모두 Component의 구현체이기 때문에 프록시를 적용할 수 있게 된다.
위의 글을 읽다보면 느낄 수 있듯이 둘이 상당히 유사하다. GOF 디자인 패턴에서 둘의 구분하는 기준은 의도라는 점을 잊지 말자.



OrderServiceConcreteProxy 는 OrderServiceV2 를 상속한다.

OrderServiceConcreteProxy.java에서 다음과 같은 에러가 발생하였다.
There is no default constructor available in 'hello.proxy.app.v2.OrderServiceV2

OrderServiceV2.java 코드이다.

OrderServiceConcreteProxy는 프록시로서의 기능만 하고, 부모 객체의 기능을 사용하지 않기 때문에 super(null);을 추가하여 에러를 해결한다.
컴포넌트를 빈에 등록하는 과정에서 @Bean 메서드를 private으로 작성하는 오타가 났었다.

public으로 수정한다.