Spring DI 방법

Spring을 처음 배울 때 Dependency Injection은
무조건 @Autowired 만을 사용하는지 알고 있었다.

하지만 @Autowired 이외에 여러 방법들이 있고,
각각의 방법들을 정리해보려고 한다.

1. Field Injection

 - 흔히 사용하는 @Autowired 를 필드 위에 달아 줌으로써 사용하는 방법이다.
 Intellij 를 사용하여 개발을 하고 있는데 @Autowired를 사용하면 아래와 같이 노란줄이 뜬다.


해석 하면 스프링 팀에서 항상 생성자 기반의 의존성 주입을 하라고 한다. : 항상 의무적인 의존성에 대해서 assertions 을 사용하라고 한다.

2. Setter Injection

 Field Injection과 유사하다.
 Setter 위에 @Autowired를 달아준다.


3. Constructor Injection

아래와 같이 생성자 에서 의존성을 주입한다.
생성자 위에 @Autowired 를 달아주었다.

하지만, 스프링 4.3 부터는 @Autowired 를 달아 주지 않아서 컨테이너가 알아서 처리할 수 있게 되었다.

그리고 아래와 같이 final 을 선언하여 의존성을 불변으로 할 수 있다.



3.1 @AllArgsConstructor

추가적으로 lombok 과 더불어서 생성자 방식을 사용 할 수 있다.
모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.

3.2 @RequiredArgsConstructor

또한 final 을 통한 불변으로 하고 싶을 때
final 이 붙은 모든 필드에 대해서 생성자 주입 방식을 적용하는 Annotation 이다.




결론

필드 방식에 대해서 정확하게 왜 권장하지 않는가에 대해서 깨달은바 중에 제일 큰 것은 
Compile 시점에서 순환참조를 감지 할 수 없다고 하는 치명적인 점 있다.

그리고 다른 글들을 찾아보면, 무책임하게 의존성의 개수가 늘어나면 SRP에 위배 된다고 하는데
이건 비즈니스에 따라서 의존성이 매우 큰 비즈니스도 있을 수 있기 때문에 
코에걸면 코걸이 귀에 걸면 귀걸이 느낌이라서 ,,, 케바케 데스네...


세터 방식은 test code 작성 시 mock bean 을 주입하거나 자유롭게 의존성을 주입 할 수 있다는 장점이 있다.
반면에, 실제 Runtime 환경에서도 어딘가에서 알 수 없는 누군가에 의해 알 수 없는 맥락에서 의존성을 변경에 대한 위험이 있다.

생성자 방식은 이러한 세터 방식의 위험성을 잡아주면서도 test code 작성 시에도 
명확하게 의존성을 주입 할 수 있다.
그리고 더불어 final 키워드를 사용할 수 있어서 compile 시점에서 
필드 및 세터 방식에서는 Runtime에서만 감지가 가능한 순환참조에 대해서도
체킹할 수 있다는 장점이 있다.
필드 및 세터 방식은 final 키워드를 사용할 수 없다.



P.S ... @Inject javax 에 있는 의존성 주입 Annotation인데 이것도 필드 인젝션이다.. 쓰지 말자.


댓글

이 블로그의 인기 게시물

About JVM Warm up

About idempotent

About Kafka Basic

About ZGC

sneak peek jitpack

Spring Boot Actuator readiness, liveness probes on k8s

About Websocket minimize data size and data transfer cost on cloud

About G1 GC

대학생 코딩 과제 대행 java, python, oracle 네 번째