객체 간의 관계, 즉 의존관계는 @Autowired를 통해 설정한다.
이러한 의존관계 주입의 방법은 네 가지가 있다.




당연한 것이나, Spring Bean이 아닌 곳에서는 @Autowired 코드가 아무 기능도 제공하지 않는다.
Spring을 포함한 대부분의 framework는 생성자 주입을 권장한다.
이유는 다음과 같다.
불변이 보장된다.
대부분의 의존관계는 한 번 설정된 이후로 프로그램 종료 시점까지 변경할 일이 없다.
따라서 Setter 주입 혹은 메서드 주입 등을 사용하면 외부에서 실수로 변경할 수 있으므로, 변경할 수 없도록생성자 주입을 권장한다.
데이터 누락 시 compile error를 발생시킨다.
Setter 주입의 경우, 의존관계 주입을 누락했을 시 실행 이후에야 NullPointException이 발생한다.
그러나 생성자 주입의 경우, 컴파일 오류가 발생함으로써 IDE를 통해 오류를 빠르게 감지할 수 있다. 이를 통해 final 키워드를 사용할 수 있게된다.
이외에도 명시성, 테스트 용이성, 순환 의존성 방지 등 여러 장점을 지니고있다.
따라서 항상 생성자 주입을 택하되 옵션이 필요한 경우에 Setter 주입을 동시에 사용하자.
기본적으로 @Autowired는 주입할 Bean이 없으면 동작하지 않는다.
만일 Bean이 없어도 동작하게끔 하려면, 다음과 같은 세 가지 방법이 있다.
@Autowired(required=false): 주입할 대상이 없으면 해당 메서드가 호출되지 않는다.

@Nuallble: 주입할 대상이 없으면null이 입력된다.

Optional<>: 주입할 대상이 없으면Optional.empty가 입력된다.

위 세 메서드에 대한 실행 결과이다.

@Autowired은 기본적으로 타입을 이용해 동작한다.
즉, ac.getBean(TypeName.class); 등의 코드처럼 동작한다.
따라서, 해당 타입의 구현체가 2개 이상일 경우 NoUniqueBeanDefinitionException 에러가 발생한다.
하위 타입으로 조회할 수도 있지만, 이는 DIP를 위배함과 동시에 유연성이 저하된다.
이를 해결하기 위한 방법인 다음 세 가지에 대해 하나씩 알아보자.
@Autowired필드명@Qualifier@Primary
@Autowired는 처음으로 타입 매칭을 시도한다.
이때 매칭되는 Bean이 여러 개인 경우, 필드명과 매칭되는 Bean을 찾는다.
위와같이 DiscountPolicy에 대한 Bean이 두 개 이상일 경우, 아래 코드는 오류를 발생시킨다.
이때, 아래와같이 필드명 discountPolicy를 rateDiscountPolicy로 변경하면, 매칭되는 Bean인 RateDiscountPolicy로 의존관계가 주입된다.

@Qualifier는 의존관계 주입시 추가 구분자를 붙이는 방법이다.
Bean 등록시 @Qualifier를 붙여주자.

이후, 의존관계 주입시에도 @Qualifier와 구분자 이름을 붙여주면 된다.
@Primary는 Bean의 우선순위를 정하는 방법이다.
RateDiscountPolicy가 FixDiscountPolicy보다 우선순위를 가지도록 하자.


좋은 정보 감사합니다.❤️❤️