Spring 에서 DI 를 어떻게 해야 잘했다고 소문날까
2021-01-06
아무생각 없이 @Autowired
를 주구장창 쓰고있었는데..
보게되는 코드 또는 블로그마다 field injection 을 기피하는 것 같길래 찾아봤더니만
intelliJ 에서도 자꾸 field injection 하지마라고 하고 ㅎㅎ;;
안 좋은 점이 있었다.
이런거 생각도 못하고 사용만했구나
일단 스프링에서 의존성을 주입받는 방법 3가지.
1. Field Injection (필드 주입)
평소에 그냥 쓰던 필드에 @Autowired
사용하는 방법이다.
@Autowired
SomeService someService;
이렇게 주입을 받게 되면 아래와 같은 단점이 존재한다.
- field 에 final 을 붙일 수가 없기 때문에, 주입받은 의존성이 변경(mutable)될 수 있다.
org.springframework.beans.factory.annotation.Autowired
의 annotation 을 사용하기 때문에, Spring DI Container 와의 의존성이 생긴다. 이것은 POJO 를 지향하는 Spring 의 관점과도 맞지 않을 뿐 더러, Test 시에도 용이하지 않다.- class 간 순환의존관계가 생겼을 떄 알 수 없다.
- 주입 받기 쉽기 때문에, 의도치 않게 여러 의존성을 주입받아서 class 간의 의존관계를 복잡하게 만들 수 있다.
2. Setter Injection (세터 메소드 주입)
SomeService someService;
@Autowired
public void setSomeService(SomeService someService) {
this.someService = someService;
}
단점은 1. Field Injection (필드 주입)
과 유사하지만, 주입받을 떄마다 setter 메소드를 만들어야된다는 점에서, 의도치않게 의존관계를 복잡하게 만들지 않을 가능성이 높다.
3. Constructor Injection (생성자 주입) -> 이렇게 하자
final SomeService someService;
public InitRunner(SomeService someService) {
this.someService = someService;
}
생성자 주입을 사용하게 되면 아래와 같은 장점이 있다.
- 주입받는 의존객체의 final 을 선언할 수 있게 되어, 불변성(immutable) 을 보장 받는다.
- 의존관계가 단순해진다. -> 개발자가 생성자를 만들 때, 의존관계가 되는 class 들을 알 수 있어서 부담스러워질 수 있다.
- class 간 순환 의존관계가 생겼을 떄 알 수 있다.
BeanCurrentlyInCreationException
발생.