@Autowired
기본은 @Autowired(required=true)로 되어있다.
@Autowired(required = false)
public void setNoBean1(Member noBean1){
System.out.println( "noBean1 = " + noBean1);
}
required = false 값으로 설정되어있다면 자동 주입할 대상이 없을경우 수정 메서드 자체가 호출이 되지않습니다.
@Autowired
public void setNoBean2(@Nullable Member noBean2) {
System.out.println("noBean2 = " + noBean2);
}
@Nullable이 있으면 주입할 대상이 없을경우 null을 리턴합니다.
@Autowired
public void setNoBean3(Optional<Member> noBean3) {
System.out.println("noBean3 = " + noBean3);
}
Optional은 주입할 대상이 있을 경우 optional내부에 값이 감싸져 있고, 없으면 Optional.empty를 리턴한다.
생성자 주입을 선택해야 하는 이유
@Autowired
public void setMemberRepository(MemberRepository memberRepository){
this.memberService = memberRepository;
}
@Autowired
public void setDiscount(DiscountPolicy discountPolicy){
this.discount = discountPolicy;
}
해당 클래스의 인스턴스 객체를 불러오고 싶을 때 어떤 구현체가 있는지 일일이 찾아가야하고,
@Test
void createOrder() {
OrderServiceImpl orderService = new OrderServiceImpl();
orderService.createOrder(1L,"item2",20000);
}
생성자를 따로 구현하지 않아 그대로 실행할경우 nullPointerException오류가 발생합니다.
@Autowired
public OrderServiceImpl(MemberRepository memberService, DiscountPolicy discount){
this.memberService = memberService;
this.discount = discount;
}
생성자를 구현하면 인스턴스 생성단계에서 구현체를 직접 넣어주지 않으면 컴파일 오류가 발생합니다.
또한 생성자를 생성해야만 역할에 final키워드를 넣을 수 있습니다
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberService;
private final DiscountPolicy discount;
final 키워드를 넣으면 좋은점이 만약에 생성자에서 변수를 지정하지 않았다면, 자바가 왜 초기화 단계에서 지정을 하지 않았냐며 컴파일오류가 발생합니다.
컴파일 오류가 세상에서 가장 빠르고 좋은 오류이다!