📢 의존성 주입할 때 생성자 주입 방식을 써야 합니다!
이전글 Lombok에 대해서 정리한 이유도 스터디를 진행하면서 @RequiredArgsContructor 어노테이션에 대해 조사하다가 Lombok을 정리해 보자! 하면서 시작했었는데요, 이번엔 해당 어노테이션이 쓰인 이유를 조사하다가 생성자 주입방식에 대해서 정리하게 됐습니다 🙂
Spring을 어느 정도 써보셨던 분들은 @Controller와 @Service에서 @Autowired가 없다면 어색하게 느껴지실 텐데요. @Autowired는 클래스와 bean 사이의 의존 관계를 맺어주는 어노테이션입니다.
생성자 주입방식을 들어가기 전에 Spring의 DI/IoC에 대해 간략하게 짚고 넘어가겠습니다.
객체를 사용자가 new 키워드를 통해 생성하고, 소멸시키는 과정 필요 없이 의존성을 주입(DI)해 Spring 컨테이너가 Bean 들의 생명 주기를 관리해 주는 기능 (IoC)입니다.
이 기능을 사용하려면 개발자가 생성한 객체를 Bean으로 등록하고 사용해야 하는데 Bean 등록은 어노테이션을 사용한 자바 코드, xml 파일 등 다양한 방법이 있습니다. 그리고 Bean을 주입받는 방식은 크게 3가지가 있습니다. (여기서 생성자 주입방식이 등장함!)
1. @Autowired - 필드주입
@RestController
public class MyController {
@Autowired
private MyRepository myRepository;
@Autowired
private MyService myService;
}
2. @setter - 수정자 주입 (메서드 주입)
@RestController
public class MyController {
private MyRepository myRepository;
private MyService myService;
@Autowired
public void setMyRepository(MyRepository myRepository){
this.myRepository = myRepository;
}
@Autowired
public void setMyService(MyService myService){
this.myService = myService;
}
}
3. 생성자 주입
@RestController
public class MyController {
private final MyRepository myRepository;
private final MyService myService;
@Autowired
public MyController (MyRepository myRepository, MyService myService){
this.myRepository = myRepository;
this.myService = myService;
}
}
이 중 가장 권장하는 방식은 생성자로 주입받는 방식입니다!!
MyController 클래스는 MyRepository와 MyService에 의존하고 있으며, 생성자 주입을 사용하여 이 의존성을 주입받고 있습니다. @Autowired 어노테이션은 Spring이 빈을 자동으로 주입하도록 지시합니다.🙂
생성자 주입 방식의 장점
💡 객체의 생성자는, 객체 생성 시 1회만 호출된다는 게 보장되는 장점이 있다.
- 불변성(Immutability) 보장
- 생성자 주입을 사용하면 주입된 의존성은 변경할 수 없음. 이로 인해 객체가 Runtime 중 변경되는 문제를 방지합니다.
- 명확한 의존성 표시
- 생성자 주입은 클래스의 의존성을 클래스의 생성자 매개변수로 명시적으로 표시함. 이렇게 하면 클래스의 의존성을 쉽게 식별하고 문서화할 수 있으며, 코드의 가독성 향상함
- 단위 테스트 용이
- 생성자 주입은 의존성을 주입하거나 대체하기 쉬우므로 단위 테스트를 수행하기 더 쉬워집니다. 테스트 중에 특정 의존성을 대체하거나 목 객체(Mock)를 주입하여 테스트 케이스를 작성하기 용이합니다.
- 순환 참조 방지
- 생성자 주입을 사용하면 순환 참조를 더 쉽게 감지할 수 있음 → 컴파일 에러 노출
- 컴파일 타임 검사
- 생성자 주입은 컴파일 타임에 매개변수의 유효성을 확인할 수 있으므로 런타임 오류를 줄일 수 있다.
- 개발자의 의존성 주입 실수 방지 (final 키워드)
- 글의 서두에 작성한 @RequiredArgsConstructor 어노테이션은 객체의 final로 정의된 필드를 포함한 생성자 선언 방식입니다.
요약
💡 생성자 주입 방식은 코드의 안정성, 가독성, 테스트 용이성, 유지 보수성을 향상하는데 많은 장점을 가지고 있으며 Spring Framework 및 다른 의존성 주입 프레임워크에서 권장하는 방식이다.
참고
'Spring > Java,Spring' 카테고리의 다른 글
Session Storage Strategy (0) | 2023.09.20 |
---|---|
Lombok 이란? (0) | 2023.09.18 |
Java 8 표준 API의 함수형 인터페이스 (0) | 2023.09.17 |
System.nanoTime & System.currentTimeMillis (feat. Intstant.now()) (0) | 2023.09.16 |
Oracle JDK & Open JDK (0) | 2023.09.15 |