@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회 호출되는것을 보장한다
따라서 불변하는 것들에 많이 사용된다.
@Component
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
System.out.println("memberRepository = " + memberRepository);
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
System.out.println("discountPolicy = " + discountPolicy);
this.discountPolicy = discountPolicy;
}
특징
선택 변경 가능성이 있는필드에 사용 가능
주입동작이 없어서 Autowired를 작동하게 하려면
Autowired(required=false)로 설정한다
@Component
public class OrderServiceImpl implements OrderService{
@AutoWired private MemberRepository memberRepository;
@AutoWired private DiscountPolicy discountPolicy;
이런식으로 바로 집어넣는방식이다.
하지만 이는 권장되지 않는다. (안티패턴)
코드가 간결하지만, 외부에서 변경이 불가능하다.
이런 경우 테스트 구성이 불편해진다.
일반 메서드를 통해 주입 받을 수 있다.
특징
한번에 여러필드 주입받을 수 있으나, 일반적으로 잘 사용하지 않는다.
자동 DI는 스프링 빈에서만 작동한다. 클라스같은데서는 아무리 @Autowired 해봤자 작동안한다.
주입할 빈이 없어도 동작해야 할 때는 Autowired값을 바꿔야한다.
Autowired만 쓰면 기본적으로 required 값이 true이다.
@Autowired(required = false)
public void setNoBean1(Member noBean1) {
System.out.println("noBean1 = " + noBean1);
}
@Autowired
public void setNoBean2(@Nullable Member noBean2) {
System.out.println("noBean2 = " + noBean2);
}
@Autowired
public void setNoBean3(Optional<Member> noBean3) {
System.out.println("noBean3 = " + noBean3);
}
required false를 쓰지 않으면, 주입할 빈이 없으면 오류가 난다.
Nullable을 쓰면 null일 경우 null 을 반환,
Optional을 쓰면 Optional.empty를 반환한다 .
대부분의 의존관계는 1회만 주입하고 변경할 일이 없고, 변해서도 안된다.
수정자 주입을 쓰면, public을 써야하고, 이는 외부에 변경이 열려있다는 뜻이다.
생성자를 써서 만들면, final을 써서 생성자로 값을 한번 넣고 다시는 안바꿀 수 있다.
롬복을 사용하면
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
이렇게만 써도 알아서 final의 생성자를 만들어준다.
이렇게 하면 코드를 많이 줄일 수 있다.