생성자를 통해서 의존관계를 주입하는 방법
- 생성자 호출 시점에 딱 1번만 호출되는 것이 보장된다.
불변
,필수
의존관계 사용- 클래스 내에 생성자가 1개만 있으면 @Autowired를 생략해도 의존관계가 자동적으로 주입된다.(스프링 빈에 해당)
필드 값을 변경하는 setter 메서드를 통해 의존관계를 주입하는 방법
선택
,변경
가능성이 있는 의존관계에 사용- 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법
- setName(), getName() 메서드를 통해 읽거나 변경하는 규칙
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired // 필수
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired // 필수
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
참고
@Autowired는 주입할 대상이 없으면 오류가 발생한다. 주입할 대상이 없어도 동작하게 하려면@Autowired(required = false)
로 지정하면 된다.
필드에 바로 주입하는 방법
- 코드가 간결해지지만, 외부에서 변경이 불가능해지므로 테스트하기 어렵다는 단점이 있다.
- DI 프레임워크가 없으면 아무것도 할 수 없다.
- 따라서 사용을 자제하는 것이 좋다. (Field injection is not recommanded 경고 발생)
- 제한적 사용
- 애플리케이션의 실제 코드와 관계 없는 테스트 코드(@SpringBootTest)
- 스프링 설정을 목적으로 하는 @Configuration 같은 곳에서만 특별한 용도로 사용
@Autowired private MemberRepository memberRepository;
@Autowired private DiscountPolicy discountPolicy;
일반 메서드를 통해 주입받을 수 있다.
- 한번에 여러 필드를 주입 받을 수 있지만, 잘 사용하지 않는다.
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
주입할 스프링 빈이 없어도 동작해야 할 경우가 생긴다. 하지만 @Autowired
만 사용하면 required
옵션의 디폴트 값은 참이므로 자동 주입의 대상이 없다면 오류가 발생한다.
자동 주입 대상을 옵션으로 처리하는 방법
@Autowired(required=false)
: 자동 주입 대상이 없다면 수정자 메서드 자체가 호출되지 않는다.org.springframework.lang.@Nullable
: 자동 주입 대상이 없다면 null이 입력된다.Optional<T>
: 자동 주입 대상이 없으면 Optional.empty가 입력된다.참고
@Nullable과 Optional은 스프링 전체에서 사용가능하다. 예를 들어서 생성자 자동 주입에서 특정 필드에만 사용할 수 있다.