이 글은 공부를 하면서 알게 된 내용들을 기록하는 글 입니다. 오류나 고쳐야 할 사항들이 있다면 지적 부탁드립니다!
<순차>
1. @Autowired란?
2. 생성자 주입
3. 수정자 주입
4. 필드 주입
5. 생성자 주입을 선택해야하는 이유
6. 생성자 주입 정리
⛅️ @Autowired란?
@Autowired란 스프링 컨테이너에 등록한 빈에게 의존관계주입이 필요할 때, DI(의존성 주입)을 도와주는 어노테이션이다.
스프링 컨테이너에 빈들을 모두 등록한 후에, 의존성 주입 단계가 이루어진다.
이 때 @Autowired 어노테이션이 부여된 메서드가 실행되며 필요한 인스턴스를 주입해준다.
@Autowired는 총 3가지 방법으로 실현이 가능한데, 생성자, 수정자(setter), 필드를 사용할 수 있다.
⛅️ 생성자 주입
● 방법 : Constructor 생성자를 통해 의존 관계를 주입하는 방법이다.
● 객체가 생성될 때 딱 한 번 호출되는 것이 보장된다 → 의존관계가 변하지 않는 경우, 필수 의존관계에 사용
● 의존 관계에 있는 객체들을 final로 선언할 수 있다는 장점 → 생성자에서 무조건 설정해주어야 함 → 누락 발생 X
● 생성자가 하나일 경우 @Autowired를 생략할 수 있다.
예를 들어 OrderService라는 클래스가 MemberRepository와 DiscountPolicy 클래스에 의존한다고 가정하자.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
의존해야하는 객체를 우선 private final로 선언한다.
그리고 생성자를 통해 해당 객체들을 주입받도록 하고, 생성자의 위에 @Autowired 어노테이션을 추가한다.
⛅️ 수정자 주입
● 방법 : setter를 생성하고, 그 위에 @Autowired를 적는다.
● 스프링 빈을 모두 등록한 후에 @Autowired가 붙은 수정자를 모두 찾아서 의존관계를 주입한다.
● "선택적"이고, "변화 가능"한 의존 관계에 사용한다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
의존해야하는 객체를 우선 private final로 선언한다.
자바 빈 프로퍼티 규약에 따라 해당 변수에 대한 Setter 메서드를 생성하고, 해당 setter에 @Autowired를 붙여서 사용한다.
⛅️ 필드 주입
● 제일 간단한 방법이다.
● 변수에 @Autowired를 붙여서 사용한다.
● 하지만 단점이 너무 많다. 어플리케이션과 관련이 없는 테스트 코드에서만 한정적으로 사용하자.
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
⛅️생성자 주입을 선택해야하는 이유
- 불변
- 대부분의 의존 관계는 어플리케이션 종료까지 변경될 일이 없다 = 불변
- 만일 수정자 주입을 사용한다면 setter를 public으로 설정해야 한다. → 실수로 변경 가능 = 좋은 방법이 아님
- 만일 생성자 주입을 사용한다면, 생성자 호출 시점에 1번 호출 → 불변하게 설계 가능
- 누락
- 프레임워크 없이 순수한 자바코드를 통해 단위 테스트하는 일이 많다.
- 수정자 주입을 사용하면 임의의 관련 객체를 만들어야한다. → 의존관계가 한 눈에 보이지 않아 누락 발생 가능
- 생성자 주입을 사용하면 누락을 막을 수 있다.
- final 키워드의 사용
- 생성자 주입 사용 시 final 키워드 사용 가능 → 생성자를 통해서만 설정 가능
- 최고의 장점 → 컴파일 오류를 통해 “누락”을 놓치지 않을 수 있다.
⛅️ 생성자 주입 정리
- 생성자 주입 → 순수한 자바 언어의 특징을 잘 살리는 방법이다
- “기본적으로 생성자 주입”을 사용하고, 필수값이 아닌 경우 setter 주입 방식을 옵션으로 부여하자. ⇒ 생성자 주입과 setter 주입을 동시에 사용할 수 있다.
- 필드 주입은 사용하지 말자!