프록시란?
프록시란 요청자와 요청을 받는자 사이에 존재하는 중간 대리인을 뜻하는 말이다.
만약 현업 부서에서 원본 코드를 수정하지 않고 로그를 기록하는 기능을 추가해 달라고 하는 상황이라고 하자.
이 문제를 어떻게 해결 할 수 있을까? 원본을 수정하지 않고 원본과 같은 인터페이스를 갖게하여(client가 대리인에게 신청하는지 server에 신청하는지 모르게 하기 위해) 로그 기능을 추가하면 되지 않을까? 이런 경우에 사용하는 것이 바로 Proxy다.
이러한 구조를 갖게 설계하면 된다. 즉 client가 server에 직접 요청하는게 아닌 대리인 Proxy에게 요청하여 간접 호출이 발생하게끔 하는 것 이다.
이렇게 직접 호출 대신 간접 호출을 하게 되면 여러가지 일을 추가적으로 할 수 있다.
ex:
이렇게 설명을 듣고 보면 아무 객체나 프록시가 될 수 있는 것 같이 들린다. 하지만 객체에서 프록시가 되려면 client는 server에게 요청을 한 것인지, 프록시에게 요청을 했는지 몰라야 한다. 즉 앞에서도 말했듯이 server와 proxy는 같은 인터페이스를 가져야 한다. 그리고 server 객체를 proxy 객체로 변경해도 client는 기존 코드를 변경하지 않고 동작할 수 있어야 한다. 즉 client는 같은 인터페이스에만 의존하게 되기 때문에 DI(Spring 핵심 기능!!)를 통해 대체 가능하다.
프록시의 주요 기능은?
프로시의 주요 기능은 접근 제어, 부가 기능 추가 이렇게 핵심적인 2가지 기능이 있다.
public interface Subject {
String operation();
}
--------------------------
@Slf4j
public class RealSubject implements Subject{
@Override
public String operation() {
log.info("real subject call");
sleep(1000);
return "data";
}
private void sleep(int millis) {
try{
Thread.sleep(millis);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
--------------------------
@Slf4j
public class CacheProxy implements Subject{
private Subject subject;
private String cacheValue;
public CacheProxy(Subject subject) {
this.subject = subject;
}
@Override
public String operation() {
log.info("proxy call");
if (cacheValue == null){
cacheValue = subject.operation();
}
return cacheValue;
}
}
--------------------------
public class ProxyPatternClient {
private Subject subject;
public ProxyPatternClient(Subject subject) {
this.subject = subject;
}
public void execute(){
subject.operation();
}
}
// sample
--------------------------
@Test
void cacheProxyTest(){
Subject realSubject = new RealSubject();
Subject cacheProxy = new CacheProxy(realSubject);
ProxyPatternClient client = new ProxyPatternClient(cacheProxy);
client.execute();
client.execute();
client.execute();
}
13:40:55.009 [main] INFO study.datajpa.pureproxy.proxy.code.CacheProxy - proxy call
13:40:55.010 [main] INFO study.datajpa.pureproxy.proxy.code.RealSubject - real subject call
13:40:56.015 [main] INFO study.datajpa.pureproxy.proxy.code.CacheProxy - proxy call
13:40:56.016 [main] INFO study.datajpa.pureproxy.proxy.code.CacheProxy - proxy call