[Spring] 07-3. @Autowired 빈 충돌

지찬우·2023년 1월 13일
0

Spring

목록 보기
23/27
post-thumbnail

이 시리즈는 인프런 강의(김영한 님의 ‘스프링 핵심 원리 - 기본편’)로 공부하며 혼자 기록하고, 사람들과도 공유할 수 있도록 작성하는 글이다. 최대한 추가적인 정보는 공식 홈페이지, 문서를 보며 얻을 예정이다.
(개인적인 생각과 이해가 들어가 있기 때문에 저의 ‘무식함’이 있을 수 있습니다😜 혹시라도 이 글을 보게 되시는 분이 계시다면 잘못된 부분 댓글로 많이 알려주시면 너무 감사하겠습니다!!)

GitHub Repository : https://github.com/jcw1031/spring-core-study


조회된 빈이 두 개 이상인 경우❗️

@Autowired는 기본이 타입으로 조회한다. 타입으로 조회하는 경우 선택된 빈이 2개 이상일 때 문제가 발생한다. DiscountPolicy의 구현체인 RateDiscountPolicyFixDiscountPolicy 둘 다 스프링 빈으로 선언되었을 때 오류가 발생한다.

RateDiscountPolicyFixDiscoutPolicy에 모두 @Component를 붙인 후, AutoAppConfigTest 클래스의 basicScan() 테스트를 실행하면 오류가 발생한다. 하나의 매칭을 기대했지만 두 개를 찾았다고 알려준다.

구체 클래스 타입으로 지정하여 주입받을 수 있지만, 이렇게 하는 경우 DIP가 위배되고 유연성이 떨어진다. 또한 이름만 다르고 똑같은 타입의 스프링 빈이 2개 이상 있을 때 해결할 수 없다.


해결 방법 💡

조회 대상 빈이 2개 이상인 경우에 해결하는 방법은 여러 가지가 있다.

  • @Autowired 필드 명 매칭
  • @Qualifier@Qualifier끼리 매칭, 빈 이름 매칭
  • @Primary 매칭

1️⃣ @Autowired 필드 명 매칭

@Autowired타입 매칭을 시도한다. 이때 여러 빈이 조회되면 필드 이름, 파라미터 이름으로 빈 이름 매칭을 시도한다.

아래처럼 필드 명이나 생성자의 파라미터 명을 통해 빈 이름을 매칭할 수 있다.

필드 명 매칭은 먼저 타입 매칭을 시도하고 여러 빈이 조회되면 추가로 동작하는 기능이다.

  1. 타입 매칭
  2. 타입 매칭의 결과가 여러 개일 때 필드 명, 파라미터 명으로 빈 이름 매칭

2️⃣ @Qualifier 사용

@Qualifier추가 구분자를 부여하는 방법이다. 빈 이름이 변경되는 것은 아니다!

빈을 등록할 때 @Qualifier 어노테이션을 붙여주고 구분자 이름을 지정한다.


주입 시에도 @Qualifier 어노테이션을 붙여주고 주입할 빈의 구분자 이름을 입력한다.

만약 @Qualifier를 통해 주입할 때 빈을 찾지 못한다면, 지정한 구분자 이름과 동일한 이름의 스프링 빈을 추가로 찾는다. 하지만 @Qualifier@Qualifier를 찾는 용도로 사용하는 것이 좋다.

  1. @Qualifier끼리 매칭
  2. 빈 이름 매칭
  3. NoSuchBeanDefinitionException 발생

3️⃣ @Primary 사용

@Primary우선순위를 지정하는 방법이다. @Autowired로 타입 매칭을 시도했을 때 여러 빈이 조회되면 @Primary가 붙은 빈이 우선권을 가진다.

RateDiscountPolicy@Primary를 붙이면, RateDiscountPolicy우선권을 갖게 되어 우선적으로 주입된다.


@Qualifier와 @Primary

실무에서는, 코드에서 자주 사용되는 메인 데이터베이스의 커넥션을 획득하는 스프링 빈과 특별한 기능으로 가끔 사용하는 서브 데이터베이스의 커넥션을 획득하는 스프링 빈이 있는 경우, 메인 데이터베이스의 커넥션을 획득하는 스프링 빈은 @Primary를 사용하고 서브 데이터베이스의 커넥션을 획득하는 스프링 빈은 @Qualifier를 사용하여 명시적으로 획득하는 방식을 사용해 깔끔한 코드를 유지하는 경우도 있다고 한다.

@Qualifier@Primary 중에 어떤 것이 우선순위가 높을까? 스프링은 자동보다 수동, 넓은 범위의 선택권보다 좁은 범위의 선택권이 우선순위가 높기 때문에 @Primary보다 @Qualifier가 우선순위가 높다.

profile
좋은 개발자가 되자.

0개의 댓글