본문 바로가기

Blog/Spring

스프링 프레임워크 입문 - 프록시 패턴

 

  • 프록시 패턴

기존 코드 건드리지 않고 새 기능 추가하기

 

Proxy 패키지

Payment 인터페이스

public interface Payment{

    void pay(int amount);

}

 

Store 클래스 // 코드 안 바뀜, 그러나 스토어를 이용한 테스트 코드에서는 프록시가 붙여나옴

public class Store{

    Payment payment;

    public Store(Payment payment){

        this.payment = payment;

    }

    public void buySomething(){

        payment.pay(100);

    }
}

 

Cash 클래스 // 코드 안 바뀜, 그러나 코드의 동작이 바뀌는 타겟임

public class Cash impleents Payment{

    @Override
    public void pay(int amount){

        System.out.println(amount + "현금 결제");

    }
}

 

CreditCard 클래스 ==> 이것이 일종의 프록시

public class CreditCard implements Payment{

    Payment payment = new Cahs();
    
    @Override
    public void pay(int amount){ 

        if(amount > 100){  // 알아서 판단
            System.out.println(amount + "신용 카드");
        }else{
            // 문제가 있을 때
            cash.pay(amount);
        }
    }
}

 

StoreTest 클래스

public class StoreTest{

    @Test
    public void tetPay(){

        Payment cashOrCard = new CreditCard();        
        Store store = new Store(cashOrCard);
        store.buySomething(100); // 100이 넘지는 않으므로 캐쉬로 구매

    }
}

위의 테스트 파일에서는 분명 Store 클래스도 바뀌지 않았고, Cash 클래스도 바뀌지 않음, Payment 인터페이스 코드도 바꾸지 않음, 그렇지만 실행할 때 다른 코드들이 생겼다. 사실상 우리는 코드를 건드리지 않았지만 클라이언트는 프록시 코드를 사용하도록 코드를 바꾼게 된다. 

기존 코드를 건드리지 않고 새로운 코드 추가(중요!!!!!!!!!!)

 

이런 일들이 스프링 aop 에서는 대부분 자동으로 이루어진다. (복잡한 메커니즘은 생략)

자동으로 빈이 등록될 때 만들어진다고 생각하면 됨

원래는 캐시라는 빈으로 등록하라고 설정해놓았기 때문에 그렇게 등록이 되어야 하는데, 내가 만들고 싶은 프록시가 자동으로 생겨서 캐시 대신에 내가 만든 프록시가 등록되고 그래서 클라이언트가 원래 빈을 등록해야 되는 캐시가 아니라 크레딧카드(캐시펄프, 스탑와치 추가 코드)를 대신 쓰게 되는 일이 스프링 내부에서 발생하게 된다. 

 

실제 예제코드는

@Transactional 붙이면 애노테이션만 붙여주면 앞뒤로 특정 코드를 넣어준다. (트랜잭션에 필요한 앞뒤 코드)

 

이걸 다 숨겨놓는 이유는 복잡하고, 비즈니스 로직에 우리가 집중하게끔 해준다. 여러 복잡한 것들의 동작은 토비 스프링을 보면 알 수 있다. 궁금하면 보셈