DI가 가능한 코드설계를 하면 다양한 패턴을 유연하게 적용 할 수 있고,
스프링은 DI를 하는데 편리한 기능들을 많이 제공하고 있습니다.
DI를 사용해서 어떤 기능을 추가할때, 기존 오브젝트를 수정하지 않고
Decorator클래스를 추가해서 동적으로 새로운 기능을 추가할 수 있습니다.
Decorator패턴
을 추가한다면 아래와 같은 구조를 갖게 됩니다.
즉, 기능 앞에 Decorator
오브젝트가 기능을 추가해 주는것입니다.
Decorator패턴
을 사용하려면 DI 설정을 해주어야 합니다.
기존에 오브젝트 앞에서Decorator패턴
이 가로채서 DI를 받고Decorator패턴
은 가로챈 오브젝트와
연결되어야 하기 때문입니다.
기존에는 DI를 받아야할 오브젝트가 1개 뿐이여서 따로 HelloController
에 DI 설정정보를 설정하지 않았습니다.
하지만 Decorator패턴
을 추가하면 HelloController
가 생성자로 주입받는 HelloService
가 2개가 되기 때문에 스프링 컨테이너가 오류를 반환합니다.
HelloController required a single bean, but 2 were found
bean이 2개이기 때문에 어떤것을 주입받을지 몰라 에러를 반환합니다.
DI를 설정하는데는
xml에 설정정보
를 주는 방법이 있고,
팩토리 메서드
를 사용하는 방법 그리고
Bean이 2개 뿐이라면
🎯@Primary
어노테이션을 사용해 우선순위를 지정할 수 있습니다.
@Service
@Primary // Bean 후보가 2개만 있을때 우선적으로 DI가 됩니다.
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) + "*";
}
}
클래스에 @Primary
를 주어서 스프링컨테이너에게 1순위로
DI를 하라고 명시하였습니다.
그럼 HelloController
에서 @Primary
가적혀있는 HelloDecorator
를 주입하고
HelloDecorator
는 또다시 생성자로 HelloService
를 주입받으니 에러가 사라지게 됩니다.
이떄, HelloDecorator
가 생성자로 HelloService
를 주입받을때 HelloService를 상속받은
남은 Bean
이 SimpleHelloService
밖에 없기 때문에 SimpleHelloService
를 상속받습니다.
프록시라는 말은 일반적으로 대리자를 뜻합니다.
실체가 존제하는데 실체 대신 어떤것을 대신해주는 것을 말합니다.
토비의 스프링 커뮤니티 답변중 토비님의 디자인 패턴에 대한 생각을 볼 수 있었습니다.
디자인 패턴에서 중요한 건 각 패턴의 목적 또는 의도입니다. 구조는 대부분 유사하기 때문에 목적으로 구분을 해야하죠.
디자인 패턴도 열심히 공부해서 적절하게 잘 구현하는 개발자가 될것입니다.