Programming/Spring
Class 형태로 Bean 접근 방법
khj1999
2025. 2. 6. 20:47
context.getBean(MyService.class)와 같이 클래스 타입으로 빈을 가져올 때, 같은 타입의 빈이 여러 개 등록되어 있다면 스프링은 어떤 빈을 반환해야 할지 몰라 NoUniqueBeanDefinitionException을 발생시킨다.
이를 해결하는 방법은 여러 가지가 있다.
1. @Primary 사용
가장 기본적인 해결책은 @Primary 애너테이션을 사용하여 우선순위를 지정하는 방법.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
@Primary // 기본 빈으로 설정
public MyService myService1() {
return new MyService();
}
@Bean
public MyService myService2() {
return new MyService();
}
}
💡 결과: context.getBean(MyService.class)를 호출하면 myService1이 반환된다.
2. @Qualifier 사용 (빈 이름 지정)
@Qualifier를 이용하여 어떤 빈을 사용할 것인지 명시적으로 지정할 수도 있다.
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("specialService")
public class SpecialService extends MyService {
}
이제 빈을 가져올 때 @Qualifier("specialService")를 사용하면 된다.
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = context.getBean("specialService", MyService.class);
myService.sayHello();
}
}
💡 결과: "specialService"로 지정한 빈을 가져옴.
3. 빈 이름을 명시적으로 사용
context.getBean("beanName", MyService.class)을 사용하면 특정 이름을 가진 빈을 가져올 수 있다.
MyService myService = context.getBean("myService1", MyService.class);
💡 결과: "myService1" 이름의 빈을 가져옴.
4. Map을 사용하여 모든 빈을 가져오기
만약 같은 타입의 모든 빈을 가져와야 한다면, Map<String, MyService> 형태로 가져와 사용할 수도 있다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class MyServiceConsumer {
private final Map<String, MyService> myServices;
@Autowired
public MyServiceConsumer(Map<String, MyService> myServices) {
this.myServices = myServices;
}
public void printServices() {
myServices.forEach((name, service) -> {
System.out.println("Bean Name: " + name);
service.sayHello();
});
}
}
💡 결과: Map을 사용하여 등록된 모든 MyService 빈을 가져와 출력.
✅ 정리
해결 방법 설명
@Primary | 기본 빈을 하나만 지정 |
@Qualifier | 특정한 빈을 명확히 지정 |
context.getBean("이름") | 빈 이름을 직접 지정 |
Map<String, Bean> | 같은 타입의 모든 빈 가져오기 |
가장 간단한 해결책은 @Primary 또는 @Qualifier를 사용하는 것이다