@Autowired란?
@Autowired는 의존성의 "타입"을 통해 찾아 주입해주는 역할을 수행하며, 생성자, setter, 필드에서 사용할 수 있다.
예컨대,
@Service
public class FoodService{
@Autowired
private FoodRepository foodRepository;
}
이렇게 사용하면 타입을 이용해 의존 대상 객체를 검색하고 할당할 수 있는 빈 객체를 찾아 주입해준다.
그런데 여기서 동일한 interface를 구현한 여러개의 클래스가 있다면?
예를 들면,
@Repository
public interface FoodRepository{
}
@Repository
public class BestFoodRepository implements FoodRepository{
}
위의 두 클래스는 Bean으로 등록될 경우 타입이 같은 빈이 된다.
이 경우 FoodRepository를 다른 Bean에서 주입할때, 같은 타입의 bean이 여러개이므로,
ioc컨테이너 측에서 어떤 것을 고를지 몰라서 구동에 실패한다.
이 문제에 대한 해결 방법은 다음과 같다.
1. @Primary 할당
같은 타입의 Bean이 여러 종류일경우 사용할 bean의 클래스에 @Primary어노테이션을 할당하면 해당 bean을 지정하여 사용하게 된다.
@Repository
@Primary
public class BestFoodRepository implements FoodRepository {
}
2. List로 받기
같은 타입의 bean이 다수일 경우 이렇게 모든 빈들을 list형태로 받아오면 된다.
@Service
public class FoodService{
@Autowired
List<FoodRepository> foodRepositories;
}
+ ) @Qualifer 어노테이션 할당
@Qualifier 어노테이션은 여러개의 타입이 일치하는 bean객체가 있을 경우 사용할 의존객체를 선택할 수 있도록 해준다. 이 @Qualifer 어노테이션을 사용하려면 두 가지를 설정해주면 된다.
1) 설정에서 빈의 Qualifer값을 명시한다.
2) @Autowired어노테이션이 있는 Object에 @Qualifer어노테이션을 설정한다. 다만 @Qualifer의 값으로 1)에서 설정한 Qualifer값을 사용한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:annotation-config/>
<bean id="food1" class="Deli.Food">
<qualifier value="best"></qualifier> <-- Qualifer값 -->
</bean>
<bean id="food2" class="Deli.Food"/>
<bean id="foodDao" class="Deli.FoodDao"/>
위와 같이 <bean>태그에 <qualifier>태그를 자식태그로 추가해서 Qualifier값을 설정한다. Qualifier 값은 value로 지정하고, 여기서는 best라고 지정하였다.
public class FoodDAO{
private Food food;
@Autowired
@Qualifier("best")
public void setFood(Food food){
this.food = food;
}
}
다음으로 @Autowired 어노테이션을 적용한 곳에 @Qualifer 어노테이션을 추가한다.
위의 설정 파일에서 food1객체를 사용하려면, @Qualifier의 값인 "best"를 지정해주면 된다.
@Qualifer로 지정해준 "best"를 가진 food1객체가 food에 주입이 된다.
정리하자면 @Autowired어노테이션이 적용되었을때 실제 의존객체를 찾는 순서는 다음과 같다.
1) 타입이 같은 빈 객체를 검색한다. 객체가 한개면 그 빈 객체를 사용한다.
2) 타입이 같은 빈 객체가 두개 이상이면, @Primary나 @Qualifier와 같은 값을 갖는 빈 객체를 찾고 존재하면 그 객체를 사용한다.
3) 타입이 같은 빈 객체가 두개 이상 있고, @Qualifier나 @Primary가 없다면 이름이 같은 빈 객체를 찾는다. 존재하면 그 객체를 사용한다.
1-3 의 경우를 모두 만족하지 않는다면 ioc 컨테이너는 Exception을 발생시킨다.
'Spring' 카테고리의 다른 글
ClassPathResource (0) | 2022.02.14 |
---|---|
thymeleaf에서 스프링 환경변수 사용하기 (0) | 2022.01.28 |
@JsonProperty (0) | 2022.01.28 |
스프링- 스프링 Bean, 생성과정과 스코프 (1) | 2021.05.18 |
스프링 - IOC와 DI (2) | 2021.05.13 |