스프링 프레임워크를 사용하다 보면, 동일한 타입의 빈(Bean)이 두 개 이상 존재할 때, 의존성 주입 시 어떤 빈을 선택할지 모호해지는 문제가 발생할 수 있습니다.
1. @Primary 애노테이션 사용
하나의 빈을 기본 빈으로 지정하여 모호성을 해결하는 방법입니다. 주입받을 때 기본으로 사용될 빈에 @Primary 애노테이션을 추가합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class AppConfig {
@Bean
public MyService myService1() {
return new MyServiceImpl1();
}
@Bean
@Primary
public MyService myService2() {
return new MyServiceImpl2();
}
}
이렇게 하면 @Autowired로 MyService를 주입받을 때 myService2가 기본적으로 주입됩니다.
2. @Qualifier 애노테이션 사용
특정 빈을 명시적으로 지정하여 주입받는 방법입니다. 빈 정의와 주입 시에 @Qualifier 애노테이션을 사용합니다.
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService1() {
return new MyServiceImpl1();
}
@Bean
public MyService myService2() {
return new MyServiceImpl2();
}
}
@Service
public class MyClient {
private final MyService myService;
@Autowired
public MyClient(@Qualifier("myService1") MyService myService) {
this.myService = myService;
}
}
이렇게 하면 myService1이 주입됩니다.
3. 빈 이름을 사용하여 주입
스프링 XML 설정이나 자바 설정을 사용할 때 빈 이름을 직접 지정하여 주입하는 방법입니다.
<bean id="myService1" class="com.example.MyServiceImpl1"/>
<bean id="myService2" class="com.example.MyServiceImpl2"/>
<bean id="myClient" class="com.example.MyClient">
<constructor-arg ref="myService1"/>
</bean>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService1() {
return new MyServiceImpl1();
}
@Bean
public MyService myService2() {
return new MyServiceImpl2();
}
@Bean
public MyClient myClient() {
return new MyClient(myService1());
}
}
4. 필드 주입 대신 생성자 주입 사용
생성자 주입을 사용하면 의존성 주입이 더 명확해지고, @Primary나 @Qualifier를 조합하여 사용하기 더 수월해집니다.
@Service
public class MyClient {
private final MyService myService;
@Autowired
public MyClient(@Qualifier("myService2") MyService myService) {
this.myService = myService;
}
}
5. @Autowired와 함께 @Qualifier 사용
빈 주입 시 @Autowired와 @Qualifier를 함께 사용하여 특정 빈을 주입할 수 있습니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class MyClient {
private MyService myService;
@Autowired
@Qualifier("myService1")
public void setMyService(MyService myService) {
this.myService = myService;
}
}
스프링 프레임워크에서는 동일한 타입의 빈이 여러 개 있을 때 의존성 주입을 명확히 하기 위해 다양한 방법을 제공합니다. @Primary, @Qualifier, 빈 이름 지정, 생성자 주입, 그리고 @Autowired와 @Qualifier를 조합하여 사용하는 방법을 통해 모호성을 해결할 수 있습니다. 각 방법은 상황에 따라 적절히 선택해서 사용하면 됩니다.