의존관계 주입은 크게 4가지 방법이 있다.
생성자를 통해서 의존 관계를 주입 받는 방법이다. 생성자 호출 시점에 딱 1번만 호출되는 것이 보장된다. (불변, 필수 의존관계에 사용) 생성자가 1개만 있으면 @Autowired를 생략해도 된다.
@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;
}
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법이다. 선택, 변경 가능성이 있는 의존관계에 사용된다.
@Autowired는 주입할 대상이 없으면 오류가 발생하기 때문에 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false)로 지정하면 된다.
@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;
}
일반 메서드를 통해서 주입하는 방법이다. 한번에 여러 필드를 주입 받을 수 있지만, 일반적으로 잘 사용하지 않는다.
@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;
}
}
주입할 스프링 빈이 없어도 동작해야 할 때는 자동 주입 대상을 옵션으로 지정할 수 있다.