스프링에는 4가지 정도의 의존관계 주입 방법이 있다.
- 생성자 주입
- 수정자 주입
- 필드 주입
- 일반 메서드 주입
일반 메서드 주입은 잘 사용하지 않기 때문에 위 세가지만 다뤄보자.
생성자 주입
대다수 개발자가 가장 선호하는 의존관계 주입 방법일 것이다. 객체 의존관계의 불변성을 보장받을 수 있고 테스트 코드를 작성할 때 객체 의존관계를 설정하기 편리하다. 또한 필드에 final 키워드를 추가하면, 생성자 주입을 이용할 때 필요한 의존 객체를 전달받지 못했을 경우 컴파일 에러가 발생하게끔 유도할 수 있다.
롬복에서는 @RequiredArgsConstructor 어노테이션을 사용하면 final 필드를 이용한 생성자를 생성해준다.
@RequiredArgsConstructor
또는 @AllArgsConstructor 어노테이션을 사용하면 모든 필드를 이용한 생성자를 생성해준다.
@AllArgsConstructor
가끔은 @NoArgsConstructor도 필요할 수 있다. 왜냐하면 JPA를 사용할 경우 프록시 객체를 생성하기 위해서 필요한 경우가 있다.
그리고 스프링 빈의 경우 생성자에 @Autowired 어노테이션을 사용하면 생성자에 필요한 의존 객체들을 자동으로 주입해준다. 다만 @Autowired 어노테이션은 당연하게도 일반 자바 코드에 사용하면 아무런 의미가 없다.
+ 그리고 스프링 빈의 생성자가 단 하나라면, @Autowired 어노테이션을 생략해도 자동으로 의존 객체들을 주입해준다.
수정자 주입
setter를 통해서 의존관계를 주입하거나 변경할 수 있는 방법이다. 개인적으로 의존관계는 런타임에 바뀌지 않는게 맞다고 생각하기 때문에 그냥 이런 게 있다 정도로 알면 될 것 같다.
필드 주입
결론부터 말하면 안하는게 좋다. 의존 관계를 직접 설정하기 어렵기 때문에 테스트 코드를 작성하기 어렵다. 프레임워크에 굉장히 의존적이라는 것도 단점이다. 그래서 스프링 부트에서는 필드 주입을 사용하면 개발자에게 경고한다.
스프링 설정을 목적으로 하는 @Configuration이나 스프링 컨테이너를 이용하는(@SpringBootTest) 테스트 코드를 작성할 때 필요한 객체들을 필드에서 @Autowired로 주입받고는 한다.
+ 스프링 빈이 없어도 동작해야 하는 경우
@Autowired는 기본 옵션이 required = true이다. 이런 경우 주입할 객체가 없으면 오류가 발생한다.
따라서 옵션을 변경하거나 다른 방법으로 회피할 수가 있다.
//호출 안됨
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
//null 호출
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
//Optional.empty 호출
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
특히 @Nullable이나 Optional<>은 쓰일 수 있는 곳이 많아서 편리하다.
reference
'Spring' 카테고리의 다른 글
같은 클래스 빈이 여러 개일 때 (0) | 2022.04.07 |
---|---|
nginx - 리버스 프록시로 스프링 CORS 문제 해결하기 (0) | 2022.04.07 |
스프링 컴포넌트 스캔 (0) | 2022.04.03 |
싱글톤의 단점과 스프링의 싱글톤 컨테이너 (0) | 2022.04.03 |
POJO에서 스프링으로의 전환 (0) | 2022.03.26 |