@Autowired가 자동 주입을 진행할때 빈을 타입으로 찾아와서 명시된 의존관계에 주입하게 되는데
이때, .getBean(DiscountPolicy.class);와 유사하게 동작한다.
이때 발생할 수 있는게 같은 타입의 스프링 빈이 두개가 있을때 NoUniqueBeanDefinitionException이 발생하는데
하위 타입으로 설정하면 이를 막을 수 있지만 이렇게 되면 OCP와 DIP를 다시 위반하게 되는 문제가 발생한다.
OCP - 확장에 열려있고, 수정에 닫혀있다. (다형성을 적극 활용하라)
DIP - 클라이언트 코드가 구체 클래스에 의존해서는 안된다.
조회 대상 빈이 2개 이상일 때 해결 방법
1) @Autowired에 필드 명을 직접적으로 매칭하는 경우
2) @Qualifier -> @Qualifer끼리 1:1 매칭 -> 빈 이름 매칭
3) @Primary 사용
1. 필드 명 직접 매칭 -> 생성자 파라미터의 이름을 빈 이름과 같게 설정
@Autowired의 경우 기본적으로 타입 매칭을 시도하고, 여러 빈이 있으면 필드 이름,
생성자의 파라미터 이름으로 빈 이름을 추가 매칭한다.
-> 즉 생성자의 타입이 인터페이스가 아니라 구체 클래스의 빈이름과 같도록 지정되면 Autowired가 빈을 찾아낼 수 있다.
2. @Qualifier 사용
주입시 넌지시 추가적인 떡밥을 던지는 것이지 빈 이름에 직접적으로 영향을 주는게 아님
@Component 애노테이션 밑에 @Qualifier를 사용하고 ()안에 문자열을 지정해줌으로써 설정가능하고
사용의 경우 생성자던 수정자던 파라미터의 타입을 지정할때, 그 옆에 @Qualifier를 붙인 뒤, ()안에 넣고자 하는 스프링 빈에 추가했던
@Qualifier 어노테이션 안에 설정했던 문자열을 그대로 입력하면 1:1로 매칭된다.
- 참고로 @Qualifier를 사용할 때 스프링 빈을 찾는것에 실패하면 다시 파라미터의 이름을 통해 스프링 빈을 조회하게 되는데, 이 경우는 생각하지 말고 @Qualifier는 명확하게 사용할 수 있는 경우에만 사용하는 것이 좋다.
결론 @Qualifier Flow
@Qualifier끼리 매칭 -> 빈 이름으로 매칭(생성자의 파라미터 이름으로 매칭) -> NoSuchBeanDefinitionException 발생
3. @Primary 사용
Primary는 우선순위를 정하는 방법이다.
@Autowired시에 여러 빈이 매칭되는 경우(찾아지는 경우) @Primary가 붙은 Spring Bean이 우선권을 가진다.
-> @Primary의 경우 메인 데이터베이스의 커넥션을 획득할 때, @Qualifier 없이 편리하게 조회할 수 있게 하고.
서브 데이터 베이스 빈의 경우 @Qualifier를 통해 명시적으로 획득하게 하는 방식으로 사용하면 깔끔하다
우선순위 -> @Primary의 경우 기본값처럼 동작하고, @Qualifier의 경우 세부적으로 동작한다.
상세한것이 우선권을 가진다. (자동 vs 수동의 예에서는 수동이 우선권을 갖듯이)
'스프링 공부 (인프런 김영한 선생님) > 스프링 핵심원리' 카테고리의 다른 글
[스프링 핵심원리] 10. 조회된 빈이 모두 필요한 경우 (0) | 2023.05.15 |
---|---|
[스프링 핵심원리] 8. 의존관계 자동 주입 (0) | 2023.05.15 |
[스프링 핵심원리] 7. Component Scan (0) | 2023.05.14 |
[스프링 핵심원리] 6. 싱글톤 컨테이너 (0) | 2023.05.10 |
[스프링 핵심원리] 5. 스프링 빈 조회 상속관계 BeanFactory와 ApplicationContext (0) | 2023.05.10 |