본문 바로가기
Spring/인프런 토비의 Spring Boot

섹션 5-3 [DI와 테스트, 디자인 패턴] DI를 이용한 Decorator, Proxy 패턴

by include_hoany 2024. 6. 12.

DI를 이용한 Decorator, Proxy 패턴

우리는 앞서 HelloController가 의존하고 있는 HelloService를 interface화 하여 의존관계의 방향을 변경하였습니다. 코드 레벨에서의 의존방향성은 변경하였지만 결국 런타임시에는 HelloController가 의존하고있는 객체 즉 실제 구현된 객체가 주입되어야 하는데 Spring Container가 Assembler역할을 수행할때 SimpleHelloService를 주입해야할지 ComplexHelloService를 주입해야할지 결정할 수 없게 됩니다.

이러한 문제점을 해소할 수 있는 방법은 의존성 주입에 우선순위를 정해주게 됩니다. 데코레이터 패턴을 예시로 들어보겠습니다.

 

HelloDecoratort.class

package com.tobyspring.tobyspringboot;  
  
import org.springframework.context.annotation.Primary;  
import org.springframework.stereotype.Service;  
/*  
    @Primary 어노테이션을 사용한다면 복수의 HelloService 구현체가 있을때  
    Spring Container가 의존성 주입을 할때 복수의 구현체중 HelloDecorator을 우선적으로  
    주입을 하게 됩니다.  
 */  
@Service  
@Primary  
public class HelloDecorator implements HelloService {  
  
    private final HelloService helloService;  
  
    public HelloDecorator(HelloService helloService) {  
        this.helloService = helloService;  
    }  
  
    @Override  
    public String sayHello(String name) {  
        return "*" + helloService.sayHello(name) + "*";  
    }  
}

 

HelloDecorator은 @Primary어노테이션을 통해 HelloService 구현체중 가장 높은 우선순위로 Spring Container가 의존성 주입을 하게 됩니다. HelloDecorator가 주입받는 HelloService는 자기 자신의 객체를 제외한(순환참조 회피) SimpleHelloService를 주입받게 됩니다. 단 여기서 HelloService를 구현한 객체가 HelloDecorator, SimpleHelloService외에 더 존재하게 된다면 Spring  Container가 HelloDecorator에 주입해야할 HelloService를 결정하지 못하게 되므로 오류가 발생하게 됩니다.

의존성 주입시에는 Proxy 패턴또한 적용할 수 있는데 HelloController가 의존성 주입받는 HelloService가 객체를 생성할때 많은 자원이 소모되어서 서버가 생성시에 해당 객체를 생성하지 않고 첫번째 요청이 있을때에 해당 객체를 생성하도록 지연 로딩을 한다던지 또는 HelloService의 실질 구현체가 로컬에 있는 객체가 아닌 외부 서버에 존재하는 객체를 사용 할 때 Proxy패턴을 통해서 이를 처리할 수 있게 됩니다.

여기서 시사하는점은 Proxy  패턴, Decoratort 패턴을 깊게 이해한다기 보다는 HelloController의 코드 변경없이 의존성 역전을 통해 기능을 유연하게 변경할 수 있다는 점 입니다.