728x90
DI 시 빈이 여러개 일때?
- @Autowired에 필요한 과정 복습
1) Component Scan + @Component로 객체를 스프링 빈에 등록
2) @Autowired를 통해 등록된 빈에서 필요한 의존관계를 설정
(우선적으로,타입(Type)으로 해당 빈(Bean)을 찾는다!)
- 만약, @Autowired를 통한 자동 의존관계 주입시 여러개의 빈을 찾는다면?
- 오류가 발생!
- 스프링은 찾은 여러개의 빈(Bean)들 중 어떤 것을 할 기준이 없기 때문
- 여러개의 빈을 찾을 때 해결할 수 있는 3가지 방법
1) @Autowired 필드 명 매칭
2) @Qualifier
3) @Primary
@Autowired 필드명 매칭
- @Autowired는 우선적으로 타입(Type)으로 빈을 찾지만, 찾지 못하면 필드 이름으로 찾는 특징이 있다.
- 내가 의존성 주입을 받는 필드 이름을 구현체의 이름으로 명시하여 찾게하는 방법
- 필드의 이름을 인터페이스가 아닌 실제 원하는 구현체의 이름으로 적용!
- 이렇게 필드명을 원하는 구현체와 일치시키면 여러개의 빈 찾을 때 해결가능
- 추천하는 방법은 X
@Primary
: @Primary 어노테이션을 붙혀서 우선순위를 지정하는 방식
(FixDiscountPolicy.java) - 고정 할인
(RateDiscountPolicy.java) - 비율 할인
- FixDiscountPolicy에 @Primary를 붙혀 @Autowired시 우선적으로 빈을 찾게 하면, 여러개의 빈을 찾을 때 원하는 대로 해결 가능!
- 실무에서 많이 사용하는 방법
@Qualifier - 기본
- 스프링 컨테이너가 여러개의 빈을 찾았을 때, 추가적으로 판단할 수 있는 정보를 주는 원리
- 선택되는 구현체들 / 사용 하는 코드 에 @Qualifier("찾는이름")을 작성해야 한다.
(FixDiscountPolicy.java) - 고정 할인
- @Qualifier("mainDiscountpolicy") 로 등록
(RateDiscountPolicy.java) - 비율 할인
- @Qualifier("subDiscountpolicy") 로 등록
[ 사용하는 코드 ]
- @Qualifier("mainDiscountpolicy") 로 추가정보를 지정!
@Qualifier - 응용
- 기본적인 @Qualifier사용을 할 때 우리는 등록한 이름을 삽입해줘야 함
--> 오타 발생해도 컴파일딴에서 걸러주지 않는다
--> 컴파일 오류(Compile Error)에서 걸러주는 방식으로 응용 가능!
1) @Qualifier를 포함한 어노테이션 추가
2) 생성한 어노테이션을 구현체에 추가
3) 생성한 어노테이션으로 사용!
정리
- @Primray와 @Qualifier를 적절히 사용하는 것이 가장 이상적
- @Primray는 하나의 구현체만을 사용하게 하는 것
- @Qualifier는 @Primary보다 귀찮지만, 디테일하게 접근하고 사용할 수 있음
--> @Primary보다 우선순위가 높다!
- 예시
: 코드에서 자주 사용하는 메인 데이터베이스 커넥션을 사용하는 빈이 있고, 코드에서 특별한 기능으로 가끔 사용하는 서브 데이터에비스의 커넥션이 있을 때- 메인 데이터베이스 커넥션을 사용하는 빈
--> @Primary로 기본설정 - 서브 데이터에비스의 커넥션을 사용하는 빈
--> @Qualifier 지정해서 명시적으로 획득! - 이렇게 하면 깔끔하게 할 수 있다
- 메인 데이터베이스 커넥션을 사용하는 빈
추가 (의도적으로 여러개의 빈 사용)
- 의도적으로 여러개의 빈을 가져와서 동적으로 처리하는 경우가 있기도 하다
- 이 때 Map / List를 사용해서 해결할 수 있다.
- 1) 생성자를 통해 DiscountPolicy타입을 가지는 모든 빈을 Map에 저장
- 2) 사용자가 discountCode로 사용할 구현체를 명시해서 넘겨준다
- 3) Map에서 discountCode에 맞는 구현체를 꺼내서 결과를 return!
728x90