Spring DI 방법
Spring을 처음 배울 때 Dependency Injection은
무조건 @Autowired 만을 사용하는지 알고 있었다.
하지만 @Autowired 이외에 여러 방법들이 있고,
각각의 방법들을 정리해보려고 한다.
Intellij 를 사용하여 개발을 하고 있는데 @Autowired를 사용하면 아래와 같이 노란줄이 뜬다.
해석 하면 스프링 팀에서 항상 생성자 기반의 의존성 주입을 하라고 한다. : 항상 의무적인 의존성에 대해서 assertions 을 사용하라고 한다.
Setter 위에 @Autowired를 달아준다.
생성자 위에 @Autowired 를 달아주었다.
하지만, 스프링 4.3 부터는 @Autowired 를 달아 주지 않아서 컨테이너가 알아서 처리할 수 있게 되었다.
모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.
세터 방식은 test code 작성 시 mock bean 을 주입하거나 자유롭게 의존성을 주입 할 수 있다는 장점이 있다.
P.S ... @Inject javax 에 있는 의존성 주입 Annotation인데 이것도 필드 인젝션이다.. 쓰지 말자.
무조건 @Autowired 만을 사용하는지 알고 있었다.
하지만 @Autowired 이외에 여러 방법들이 있고,
각각의 방법들을 정리해보려고 한다.
1. Field Injection
- 흔히 사용하는 @Autowired 를 필드 위에 달아 줌으로써 사용하는 방법이다.Intellij 를 사용하여 개발을 하고 있는데 @Autowired를 사용하면 아래와 같이 노란줄이 뜬다.
해석 하면 스프링 팀에서 항상 생성자 기반의 의존성 주입을 하라고 한다. : 항상 의무적인 의존성에 대해서 assertions 을 사용하라고 한다.
2. Setter Injection
Field Injection과 유사하다.Setter 위에 @Autowired를 달아준다.
3. Constructor Injection
아래와 같이 생성자 에서 의존성을 주입한다.생성자 위에 @Autowired 를 달아주었다.
그리고 아래와 같이 final 을 선언하여 의존성을 불변으로 할 수 있다.
3.1 @AllArgsConstructor
추가적으로 lombok 과 더불어서 생성자 방식을 사용 할 수 있다.모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.
3.2 @RequiredArgsConstructor
또한 final 을 통한 불변으로 하고 싶을 때
final 이 붙은 모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.
final 이 붙은 모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.
결론
필드 방식에 대해서 정확하게 왜 권장하지 않는가에 대해서 깨달은바 중에 제일 큰 것은
Compile 시점에서 순환참조를 감지 할 수 없다고 하는 치명적인 점 있다.
그리고 다른 글들을 찾아보면, 무책임하게 의존성의 개수가 늘어나면 SRP에 위배 된다고 하는데
이건 비즈니스에 따라서 의존성이 매우 큰 비즈니스도 있을 수 있기 때문에
코에걸면 코걸이 귀에 걸면 귀걸이 느낌이라서 ,,, 케바케 데스네...
세터 방식은 test code 작성 시 mock bean 을 주입하거나 자유롭게 의존성을 주입 할 수 있다는 장점이 있다.
반면에, 실제 Runtime 환경에서도 어딘가에서 알 수 없는 누군가에 의해 알 수 없는 맥락에서 의존성을 변경에 대한 위험이 있다.
생성자 방식은 이러한 세터 방식의 위험성을 잡아주면서도 test code 작성 시에도
명확하게 의존성을 주입 할 수 있다.
그리고 더불어 final 키워드를 사용할 수 있어서 compile 시점에서
필드 및 세터 방식에서는 Runtime에서만 감지가 가능한 순환참조에 대해서도
체킹할 수 있다는 장점이 있다.
필드 및 세터 방식은 final 키워드를 사용할 수 없다.
필드 및 세터 방식은 final 키워드를 사용할 수 없다.
P.S ... @Inject javax 에 있는 의존성 주입 Annotation인데 이것도 필드 인젝션이다.. 쓰지 말자.
댓글
댓글 쓰기