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 Kafka Basic

About JVM Warm up

About ZGC

Spring Boot Actuator readiness, liveness probes on k8s

About G1 GC

sneak peek jitpack

About idempotent

C 언어 구조체의 포인터 멤버 변수

Synology NAS에 MariaDB 10에 Mysql workbench로 원격접속하기

About Websocket minimize data size and data transfer cost on cloud