Spring

@Qualifier 알아보기

자바지기 2022. 11. 8. 02:22
반응형

@Qualifier 란?

자동 주입 가능한 빈이 두 개 이상일 때, 자동 주입할 빈을 지정할 수 있는 어노테이션이다.

 

예시 코드를 통해 @Qualifier를 사용해야 하는 상황을 확인해보자.

 

아래와 같이 MemberDao를 자동 주입 받는 MemberService가 존재한다.

 

그리고 MemberDao를 자동 주입 받을 수 있게 Bean으로 등록해주는 설정 파일은 다음과 같다.

 

이 상황에서 MemberDao 타입의 Bean을 하나 더 생성하면 어떻게 될까?

 

다음과 같이 설정 파일에 memberDao2를 추가했을 때,

 

자동 주입을 받는 쪽에서 다음과 같은 문제가 발생한다.

 

자동 주입 가능한 Bean이 두 개이상이므로 특정 Bean을 주입할 수가 없어서 발생하는 문제이다.

 

이 문제를 해결하려면 어떻게 해야할까?

 

방법 1: Bean의 이름과 주입받는 곳의 변수의 이름을 일치시킨다.

이 방법은 이 테스트를 만들다가 발견했다.

현재 Bean으로 등록된 MemberDao 타입의 Bean들의 이름은 memberDao1, memberDao2이다.

이때 MemberService 내부 변수의 이름을 memberDao1로 바꾸었더니, 자동 주입으로 memberDao1 Bean이 주입되었다.

 

다음의 코드를 실행해서 결과를 출력해보았더니 결과로 true가 출력되었다.

그러나 아래의 코드를 실행했을 때는 false가 출력됨을 확인할 수 있었다.

System.out.println(memberService.getMemberDao1() == ctx.getBean("memberDao2"));  // false

 

이렇게 하여 같은 타입의 Bean이 여러 개 등록되어도 주입받을 변수의 이름을 통해서 구분할 수 있음을 알게 되었다.

이 방법은 되게 간단하게 해결되지만, 많은 문제들이 존재할 것 같다.

 

MemberService 내부 변수 이름이 바뀌거나, Bean 객체 이름이 변경될 경우 의도치 않은 Bean이 주입될 수 있다.

 

 

방법 2: @Qualifier를 사용한다.

@Qualifier를 통해 주입을 원하는 Bean을 등록할 수 있다. 

@Qualifier는 두 위치에서 사용 가능하다.

 

첫 번째로는 주입받고 싶은 곳에 @Qualifier를 작성한다.

이렇게 작성하면 memberDao에 memberDao1 이름을 갖는 Bean이 자동 주입된다.

 

두 번째로는 @Bean 애노테이션을 붙인 Bean 설정 메서드이다.

위와 같이 Bean 설정 메서드에 @Qualifier("hello")를 붙이고,

 

위와 같이 자동 주입받을 곳에 @Qualifier("hello")을 붙이면 마찬가지로 memberDao1 Bean이 자동 주입된다.

 

이 테스트를 진행하는 과정에서 궁금증이 하나 생겼다.

 

궁금증 1.  Bean 객체 등록 시 @Quailifier에 작성된 값으로 Bean 이름이 등록될까?

디버그를 통해 확인한 결과, @Qualifier에 작성된 값으로 등록되지 않고, memberDao1로 등록되었다.

 

궁금증 2. @Qualifier에 작성된 값이 이미 Bean으로 등록되어있다면 어떤 Bean 객체를 주입받을까?

 

위와 같이 memberDao1에 @Qualifier("memberDao2")를 작성하고,

자동 주입 받을 곳에서도 마찬가지로 @Qualifier("memberDao2")를 작성해보았다.

 

결과는 에러가 발생했다.

cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberService': Unsatisfied dependency expressed through field 'memberDao'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.springtest.spring5.spring5_chapter4.dao.MemberDao' available: expected single matching bean but found 2: memberDao1,memberDao2

 

NoUniqueBeanDefinitionException이 발생한다. 매치되는 Bean 객체가 2개이기 때문에 발생했다.

 

 

정리

같은 타입의 Bean 객체가 2개 이상이라면 주입받고 싶은 Bean 객체에 @Qualifier를 적용하자.

이때 @Qualifier에 작성된 값이 다른 Bean 객체의 이름과 겹치는 것에 주의하자.

그리고 @Qualifier는 의존 주입을 받을 곳과 Bean 객체 설정하는 곳 두 군데 모두 작성하자 

반응형