생성자 주입
불변 : 처음에 세팅한 값을 변경하는 것을 허용하지 않는 것
필수 : 변수에 final 키워드를 적용하면 무조건 값이 초기화되어야 한다. 따라서 해당 필드가 초기화되어있지 않으면 컴파일 오류를 발생시킨다. 생성자로 해당 필드를 필수로 초기화해야한다.

생성자가 딱 1개만 있으면 @Authwiired를 생략해도 자동 주입된다.
수정자 주입(Setter 주입)

필드 주입

@SpringBootTest 처럼 스프링 컨테이너를 테스트에 통합한 경우에만 가능하다.
일반 메서드 주입

생성자 주입을 권장하는 이유
불변
누락
프레임워크 없이 순수한 자바 코드를 단위 테스트하는 경우는 굉장히 많다.
이때 수정자 의존관계 등을 사용한다면, 만약 실수로 setter를 호출하여 의존관계를 주입하는 것을 누락한다면, Null Point Exception 등의 런타임 에러가 발생할 수 있다.
하지만 생성자 주입을 사용한다면 실수로 주입 데이터를 누락했을 때 런타임 에러가 아닌 컴파일 오류가 발생한다. 컴파일 오류는 세상에서 가장 빠르고, 좋은 오류다!!
즉, IDE에서 바로 어떤 값을 누락했는지 쉽게 파악할 수 있다. 따라서 수정자 주입보다 누락을 쉽게 잡을 수 있다.
final 키워드
생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있다. 따라서 생성자에서 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에 막아준다. 수정자 주입등의 나머지 주입 방식은 모두 생성자 호출 이후에 호출되므로, 필드에 final 키워드를 사용할 수 없다.
결론 : 그냥 생성자 주입 방식을 사용하고 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다. (생성자 주입과 수정자 주입을 동시에 사용할 수 있다.)
출처 : 출처
조회 빈이 2개 이상일 때
조회한 빈이 모두 필요할 때
예를 들어 할인 서비스를 제공하는데, 클라이언트가 할인의 종류(rate, fix)를 선택할 수 있다면은 의도적으로 정말 해당 타입의 스프링 빈이 다 필요하다.


로직 분석
DiscountService는 Map으로 모든 DiscountPolicy 를 주입받는다. 이때 fixDiscountPolicy ,rateDiscountPolicy 가 주입된다.
discount () 메서드는 discountCode로 "fixDiscountPolicy"가 넘어오면 map에서
fixDiscountPolicy 스프링 빈을 찾아서 실행한다. 물론 “rateDiscountPolicy”가 넘어오면
rateDiscountPolicy 스프링 빈을 찾아서 실행한다
주입 분석
Map<String, DiscountPolicy> : map의 키에 스프링 빈의 이름을 넣어주고, 그 값으로
DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담아준다.
List : DiscountPolicy 타입으로 조회한 모든 스프링 빈을 담아준다.
만약 해당하는 타입의 스프링 빈이 없으면, 빈 컬렉션이나 Map을 주입한다.
자동, 수동의 올바른 실무 운영 기준
애플리케이션은 크게 업무 로직과 기술 지원 로직으로 나눌 수 있다.
애플리케이션에 광범위하게 영향을 미치는 기술 지원 객체는 수동 빈으로 등록해서 딱! 설정 정보에 바로 나타나게 하는 것이 유지보수 하기 좋다!
비지니스 로직중에서 다형성을 적극 활용할 때 어떤 빈들이 주입될 지, 각 빈들의 이름은 무엇일지 코드만 보고 한번에 쉽게 파악하기 쉽지 않기에 수동 빈으로 등록하거나 또는 자동으로 하면 특정 패키지에 같이 묶어두는게 좋다!