의존관계 주입은 크게 4가지 방법이 있다.
- 생성자 주입
- 수정자 주입(setter 주입)
- 필드 주입
- 일반 메서드 주입
생성자 주입
생성자를 통해서 의존관계를 주입받는 방법이다.
@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;
}
}
생성자 호출 시점에 의존관계를 주입하므로 딱 1번만 수행되는 것이 보장된다.
주입된 필드의 값을 변경할 수 없기 때문에 불변, 필수 의존관계에 사용된다.
생성자가 딱 1개만 있을 경우 @Autowired를 생략해도 자동 주입된다.
수정자(setter) 주입
setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해 의존관계를 주입하는 방법이다.
@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;
}
}
주입된 필드의 값을 변경할 수 있기 때문에 선택, 변경 가능성이 있는 의존관계에 사용된다.
자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법이다.
필드 주입
필드에 바로 주입하는 방법이다.
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
외부에서 변경하기 불가능하여 테스트하기 힘들다는 단점이 있다.
DI 프레임워크 없이는 아무것도 할 수 없다.
일반 메서드 주입
일반 메서드를 통해 주입받을 수 있다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
한 번에 여러 필드를 주입받을 수 있다.
여러 가지 의존관계 주입 방법 중 어느 것을 선택해야 할까?
권장하는 방법은 생성자 주입이다.
대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료 시까지 변경할 일이 없고 변하면 안 된다.
만약 수정자 주입을 사용하게 된다면 set 메서드를 통해 의도치 않은 의존관계 변경이 일어날 수 있고, 변경하면 안 되는 메서드를 열어두는 것은 좋은 설계 방식이 아니다.
또한 순수한 자바 코드로 테스트 코드 작성 시 수정자 주입을 사용한다면 의존관계를 누락할 수 있지만, 생성자 주입을 사용하면 주입 데이터를 누락했을 시 컴파일 오류가 발생하여 쉽게 알 수 있다.
마지막으로 생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있다. 그래서 생성자에서 값이 설정되지 않는 오류를 컴파일 시점에 막아준다.
'Spring' 카테고리의 다른 글
[Spring] 빈 생명주기 콜백 (0) | 2022.12.28 |
---|---|
[Spring] 같은 타입으로 조회된 빈이 여러 개일 경우 (0) | 2022.12.28 |
[Spring] 컴포넌트 스캔 (0) | 2022.12.27 |
[Spring] 싱글톤 패턴과 싱글톤 컨테이너 (2) | 2022.12.26 |
[Spring] 스프링 컨테이너와 스프링 빈 (0) | 2022.12.26 |