[Spring] 왜 생성자 주입을 선택해야 할까 (with Modularity)?

soonhankwon·2023년 10월 10일
0
post-thumbnail

최근에는 스프링을 포함한 DI 프레임워크 대부분이 생성자 주입을 권장하는 트렌드입니다.

일단 모던 소프트웨어 디자인에서 DI를 하는 가장 중요한 이유는 Modularity 라고 합니다.

아래에서는 간단하게 Modularity 에 연관해서 스프링에서의 DI를 살펴보고, 왜 스프링에서 생성자 주입을 선택하는 것을 권장하는지 살펴보겠습니다.

Modularity

Figure 33. Overview of the high and low modularity in a graph (Ref. [128]).

그래프 이론에서 나온 지표이고 산출하는데 복잡한 수식을 가지고 있습니다. 하지만 간단히 말하자면 Modularity 가 높을수록 그래프가 잘 분할되었다. 즉 뚜렸한 목적을 가진 녀석들이 독립적으로 모였다라고 말할 수 있습니다.

Spring Bean

  • 뚜렸한 목적을 가진 녀석이 기능을 수행하기 위해 모듈화된것 이라고 말할 수 있습니다.
    • 독립적인 모듈 또는 컴포넌트

DI (Dependency Injection)

기존에는 프로그래머가 프로그램 흐름에서 객체를 생성해서 사용했습니다.

  • 직접적으로 객체를 생성하거나 의존 → 결합도가 높다.

하지만 DI 프레임워크에서는 컨테이너가 객체를 관리하며 주입해줍니다.

  • 모듈화된 녀석들을 프로그래머가 아닌 컨테이너가 주입해주는 것 (IoC)

느슨한 결합

  • 외부에서 의존성을 주입하기 때문에 모듈이 독립적으로 존재하고 변경사항에 대해 덜 영향을 받습니다.
    • 하지만, 공유 및 변경가능한 필드가 모듈에 있다면?
    • 필드가 스레드간 마구잡이로 돌아다니며 예측하지 못하는 결과를 유발할 것입니다.
    • 그래서 보통 스프링빈에 공유 및 변경가능한 필드를 사용하는 것은 지양하는 것을 볼 수 있습니다.

이밖에 테스트 용이성, 재사용성, 유연성 면에서 장점이 있습니다.

스프링에서의 DI 방법

스프링에서의 대표적인 DI 방법은 다음과 같이 3가지가 있습니다.

  • 필드 주입
  • Setter 주입
  • 생성자 주입

필드 주입과 Setter 주입의 문제점 - 모듈화의 관점

대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없습니다.

이는 대부분의 의존관계애플리케이션 종료 전까지 변하면 안된다는 것을 다른 한편으로는 의미합니다.

여기서 필드 주입과 Setter 주입의 문제점이 발생합니다.

필드 주입과 Setter 주입은 필드를 final 로 선언하지 못합니다.

  • 모두 생성자 이후에 호출되기 때문입니다.
  • 이는 곧 모듈의 변경 가능성을 뜻한다고 생각합니다.
    • 또한 Setter 주입은 접근 제어자를 public 으로 선언해야합니다.
  • 대부분의 의존성은 불변해야 하는데 어디에선가 실수로 변경할 가능성을 지니고 있습니다.

생성자 주입의 장점

생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있습니다.

그래서 생성자에서 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에 막아줍니다.

  • 또한 생성자 호출 이후 DI 받은 필드가 변경되는것을 애초에 컴파일 시점에 막아줌으로써 변경가능성을 애초에 차단합니다.

Summary.

결국 스프링에서 생성자 주입을 사용하는 것이 모듈화의 관점에서도 쫌 더 나은 DI 방법이라고 생각합니다.

물론 변경이 필요한 상황의 경우 Setter 주입을 사용하면 될 것입니다만, 이 경우도 쫌 더 나은 DI 방법이 있다고 생각합니다.

  • ex) Configuration 을 사용해서 조건에 따른 Dependency 주입
profile
ProblemOverFlow

0개의 댓글