의존관계 주입은 크게 4가지 방법이 있다.
1. 생성자 주입
2. setter 주입
3. 필드 주입
4. 일반 메서드 주입
생성자 주입
생성자 주입은 생성자를 통해 의존 관계를 주입 받는 방법이다. 가장 추천되는 방법이다.
생성자 주입은 생성자 호출 시점에 딱 1번만 호출되는 것이 보장된다.
또한, 필드를 final로 선언할 수 있기 때문에 런타임에 객체의 불변성을 보장한다.
따라서 불변, 필수 의존 관계에 사용된다.
※ 생성자가 1개만 있을 경우 @Autowired 생략이 가능하다.
생성자가 2개 이상일 때 @Autowired를 생략할 경우 오류가 발생한다.
@Component
public class MyApp {
// 필드에 final 키워드 필수! (필수)
private final MyService myService;
// 생성자를 통해 의존성 주입
@Autowired
public MyApp(MyService myService) {
this.myService = myService;
}
...
}
setter 주입
setter주입은 setter 메서드를 사용해 의존관계를 주입해주는 방법이다.
선택, 변경 가능성이 있는 의존 관계에 사용한다.
@Component
public class MyApp {
private MyService myService;
// Setter 주입
@Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
...
}
Setter 주입을 사용할 경우 final로 선언할 수 없기 때문에 외부에서 내부 필드에 접근할 수 있고, 이는 변경의 여지가 있음을 의미한다. 또한, Setter 주입은 객체가 생성된 이후에 의존성이 주입되기 때문에 객체의 일관성을 보장하기 어렵다.
따라서 Setter 주입 역시 추천되지는 않는다.
필드 주입
필드에 직접적으로 주입하는 방법이다.
코드가 간결하다는 장점이 있지만,
Spring(DI 프레임워크)이 없으면 사용할 수 없고, 외부에서 값을 설정하는 것이 불가능하기 때문에 결국 Setter를 만들어야한다. 무엇보다 테스트 코드 작성이 어렵다. 따라서 사용하지 않는 것이 좋다.
@Component
public class MyApp {
@Autowired
private MyService myService; // 필드에 직접 주입, final로 설정 불가
...
}
일반 메서드 주입
일반 메서드를 통해 의존관계를 주입해주는 방식이다.
한 번에 여러 필드를 주입 받을 수 있다는 장점이 있다.
하지만 생성자, setter 주입으로 대체가 가능하기 때문에 잘 사용되지 않는다.
+) 의존 관계 자동 주입은 스프링 빈에만 해당한다. 스프링 빈이 아닌 클래스에 @Autowired를 사용해도 아무 기능도 동작하지 않는다.
@Component
public class MyApp {
private MyService myService;
private MyRepository myRepository;
// 일반 메서드 주입
@Autowired
public void init(MyService myService, MyRepository myRepository) {
this.myService = myService;
this.myRepository=myRepository;
}
...
}
좋은 참고 자료:
https://madplay.github.io/post/why-constructor-injection-is-better-than-field-injection
'TIL > Spring' 카테고리의 다른 글
[TIL] Pageable, PageRequest - 페이지네이션 (0) | 2024.12.10 |
---|