개발자가 직접 생성하는 것이 아니라 외부에서 의존성을 주입하는 것을 의존성 주입이라고 한다.
✔ 방법 5가지
✔ 옵션 처리 : 주입할 스프링 빈이 없을 때도 동작하도록->주입할 스프링 빈이 없으면 오류가 나는데 그 오류가 나지 않도록 하는 것이 옵션처리
@Autowired(required = false)
public void setNoBean1(Member member) {
@Autowired
public void setNoBean2(@Nullable Member member) {
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
✔ 생성자 주입을 선택하자!!
✔ 롬복 : final이 붙은 필드를 모아 생정자를 자동으로 만들어 준다
순서 : 생성자 주입에서 생성자가 딱 1개 존재하는 경우 -> @Autowired생략->@RequriedArgsConstructor를 사용하여 생성자도 생략
@Component
@RequriedArgsConstructor
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
✔ 조회 빈이 2개 이상 즉 같은 타입의 빈이 2개 이상인 경우
@Autowired는 타입으로 조회화여 의존관계를 만든다.
해결방법
@Autowired
private DiscountPolicy rateDiscountPolicy
@Qualifier 사용
만약 mainDiscountPolicy라는 Qualifier를 못 찾으면 저 이름을 가진 스프링 빈을 찾는다.
그 스프링도 못 찾으면->NoSuchBeanDefinitionException 발생
@Primary 사용
애노테이션 직접 만들기 : @Qualifier 사용의 경우 컴파일할 때 타입체크가 불가능
✔ 조회 빈이 2개 이상인데 조회한 빈이 모두 필요한 경우 List, Map
여러개일 때 사용자가 선택할 수 있도록 바꾸기
이럴 경우 우리는 Map<String, DisscountPolicy>와 List를 필수 인자로 받는 생성자를 갖는 클래스 객체를 컴포턴트로 등록하고 생성자 의존관계 주입을 한다.
중요한 것은 스프링 컨테이너에 2개 클래스에 있는 객체들을 담는 것이다.
스프링 빈으로 담을 때 생성자 주입을 통해서 생성자가 생성되며 이게 스프링 빈에 담긴다.
사용자로부터 입력을 받기 위해서 DiscountService에 메소드를 추가한다.
discount() 메서드의 discountCode로 메시지가 넘어온다.
policyMap이 Map이기 때문에 키값으로 객체를 선택할 수 있도록 구현됨
사용자로부터 입력 받기
✔ 자동 VS. 수동
자동을 선호하는 추세 그러나!
기술 지원 로직(데이터베이스 연결이나 공통 로그 처리처럼 업무 로직을 지원하기 위한 하부 기술이나 공통기술)은 수동으로 한다. 왜냐하면 너무 광범위해서 어디서 문제가 발생하면 파악하기 어렵기 때문에 세심하게 관리한다.
다형성의 경우 자동 등록 스프링 빈들은 같은 패키지에 수동등록은 같은 클래스에 두기