@Configuration 어노테이션이 선언된 클래스내에서,
@Bean 어노테이션이 선언된 메소드는 다른 빈에 의존하여 자신을 초기화 할 수 있다.
이 때, 다른 빈이 파라미터로 들어올 때, 자동주입이 가능하다. 예시로 확인해보자.
1. 타입 자동주입
들어오는 파라미터의 타입이 선언된 빈이 하나라면, 해당 빈을 자동으로 주입해준다.
2. 이름 자동주입
만약 위와 같이 BeanA 라는 인스턴스 2개가 빈으로 등록되어 있다면? 이 때는 타입으로만 판단하기에 모호하기에
이름이 같은 빈을 주입해준다.
※ Bean 의 이름?
@Bean 어노테이션이 달린 메소드의 기본 이름은 메소드명이 된다. 위 같은 경우에는 bean1, bean2 가 된다.
그 외에도 개발자가 원하는 이름을 설정 하기 위해선 @Bean(name="...") 과 같이 이름을 설정할 수 있다.
3. @Qualifier 어노테이션
파라미터로 선언할 때 이름이 선언된 빈과 일치하면 2번 케이스로 해결하겠지만, 그렇지 않은 경우에는 어떡할까?
이 때는 @Qualifier 로 빈의 이름을 명시해서 어떤 인스턴스인지 명확하게 명시해줄 수 있다.
4. @Qualifier 어노테이션 + 이름
Bean의 이름으로도 자동주입이 가능하지만, @Qualifer 어노테이션에 이름을 지정하고 그에 따른 자동주입도 가능하다.
※ Bean의 이름 vs Qualifier 이름
// 1번 케이스
@Bean(name = "bean1")
public A getA() {
return new A();
}
---------------------------
// 2번 케이스
@Bean
@Qualifier("bean1")
public A getA() {
return new A();
}
@Autowire
public void test(@Qualifier("bean1") A a) {
...
}
그러면 @Bean의 이름과 @Qualifier의 이름을 명시하는거의 차이가 무엇일까? 자동주입된다는 사실은 같은데 말이다.
@Bean(name= "...") 은 스프링 컨텍스트에서 빈의 이름을 설정한다. 빈 이름 같은 경우에는 고유 식별자이므로, 하나의 빈 이름만 가질 수 있지만, @Qualifier 의 이름은 여러개를 가질 수가 있다. 아래 예시를 보자.
@Component
@Qualifier("beanQualifier")
class BeanTwo implements TypeOne { }
@Component
@Qualifier("beanQualifier")
class BeanThree implements TypeOne { }
@Qualifier 이름이 같은 두 인스턴스가 있을 때,
@Autowired
@Qualifier("beanQualifier")
Map<String, TypeOne> typeOneMap;
// 결과 : {beanThree=BeanThree@9f674ac, beanTwo=BeanTwo@1da4b3f9}
위와 같이 자동주입을 수행했을 때 맵에는 두개의 인스턴스가 들어가게 된다.
참조
https://stackoverflow.com/questions/62822167/spring-beanname-name-vs-bean-qualifiername
'자바' 카테고리의 다른 글
Iterable, Iterator, ListIterator (4) | 2024.10.09 |
---|---|
[Java] 자바 제네릭, Generic 문법 (1) | 2023.10.03 |