[SPRING] 봄은``유형의 하나 이상의 콩이있다, autowire가 없습니다
SPRING봄은``유형의 하나 이상의 콩이있다, autowire가 없습니다
여기에 내 질문 : 저는 기본 인터페이스와 두 개의 구현 클래스가 있습니다.
그리고 서비스 클래스는 기본 인터페이스에 대한 종속성이, 코드는 다음과 같다 :
@Component
public interface BaseInterface {}
@Component
public class ClazzImplA implements BaseInterface{}
@Component
public class ClazzImplB implements BaseInterface{}
그리고 구성은 다음과 같이이다 :
@Configuration
public class SpringConfig {
@Bean
public BaseInterface clazzImplA(){
return new ClazzImplA();
}
@Bean
public BaseInterface clazzImplB(){
return new ClazzImplB();
}
}
서비스 클래스는 코드는 다음과 같다 logic.And 일부 비즈니스로하는 구현 autowire하기로 결정합니다 기본 인터페이스에 종속
@Service
@SpringApplicationConfiguration(SpringConfig.class)
public class AutowiredClazz {
@Autowired
private BaseInterface baseInterface;
private AutowiredClazz(BaseInterface baseInterface){
this.baseInterface = baseInterface;
}
}
그리고 IDEA는 예외를 throw :하지 autowire.There이 BaseInterface 유형의 하나 이상의 콩입니다 수 있습니다.
이 예선 @ 사용하여 해결할 수 있지만, 그러나이 상황에서 나는 종속 클래스를 선택할 수 없습니다.
@Autowired
@Qualifier("clazzImplA")
private BaseInterface baseInterface;
나는 봄 문서를 읽고는 생성자 의존성 주입을 제공하기 위해 노력하지만 여전히 문제로 혼란스러워하고 있습니다.
그 누구도 날 도와 드릴까요?
해결법
-
==============================
1.봄은 구성 클래스에 이러한 수정 사항을 적용, 유선됩니다 정확한되는 콩 지정하여 혼란을 제거하기 위해 @Autowired와 함께 당신이 @Qualifier 어노테이션을 사용할 수 있도록 당신이 구성 클래스에서 선언 한 2 콩 사이에 혼란
봄은 구성 클래스에 이러한 수정 사항을 적용, 유선됩니다 정확한되는 콩 지정하여 혼란을 제거하기 위해 @Autowired와 함께 당신이 @Qualifier 어노테이션을 사용할 수 있도록 당신이 구성 클래스에서 선언 한 2 콩 사이에 혼란
@Configuration public class SpringConfig { @Bean(name="clazzImplA") public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean(name="clazzImplB") public BaseInterface clazzImplB(){ return new ClazzImplB(); } }
다음 @Autowired 주석에
@Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired @Qualifier("the name of the desired bean") private BaseInterface baseInterface; private AutowiredClazz(BaseInterface baseInterface){ this.baseInterface = baseInterface; } }
-
==============================
2.이 스프링 프레임 워크 만 사용하여 해결할 수 없습니다. 당신은 어떤 논리에 따라 당신이 BaseInterface의 인스턴스를 필요가 있다고 언급했다. 이 유스 케이스는 공장 패턴을 사용하여 해결할 수 있습니다. 실제로 BaseInterface의 팩토리 인 콩 만들기
이 스프링 프레임 워크 만 사용하여 해결할 수 없습니다. 당신은 어떤 논리에 따라 당신이 BaseInterface의 인스턴스를 필요가 있다고 언급했다. 이 유스 케이스는 공장 패턴을 사용하여 해결할 수 있습니다. 실제로 BaseInterface의 팩토리 인 콩 만들기
@Component public class BaseInterfaceFactory{ @Autowired @Qualifier("clazzImplA") private BaseInterface baseInterfaceA; @Autowired @Qualifier("clazzImplb") private BaseInterface baseInterfaceB; public BaseInterface getInstance(parameters which will decides what type of instance you want){ // your logic to choose Instance A or Instance B return baseInterfaceA or baseInterfaceB } }
구성 (뻔뻔하게 다른 의견에서 복사)
@Configuration public class SpringConfig { @Bean(name="clazzImplA") public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean(name="clazzImplB") public BaseInterface clazzImplB(){ return new ClazzImplB(); } }
서비스 클래스
@Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired private BaseInterfaceFactory factory; public void someMethod(){ BaseInterface a = factory.getInstance(some parameters); // do whatever with instance a } }
-
==============================
3.당신은 @Autowired를 사용하는 경우, Spring은 autowire하기 할 필드의 유형과 일치하는 빈을 검색합니다. 귀하의 경우에는 유형 BaseInterface 하나 이상의 콩이 있습니다. 즉 봄이 분명하게 일치하는 빈을 선택할 수 없습니다.
당신은 @Autowired를 사용하는 경우, Spring은 autowire하기 할 필드의 유형과 일치하는 빈을 검색합니다. 귀하의 경우에는 유형 BaseInterface 하나 이상의 콩이 있습니다. 즉 봄이 분명하게 일치하는 빈을 선택할 수 없습니다.
이러한 상황에서 명시 적으로 사용하거나 모호성을 해결해야 콩 봄을 상태로 다른 선택의 여지가 없다.
-
==============================
4.이보다 쿨러 솔루션은 구현 자체가 그들이 적용 할 수 있는지 확인하기 위해 논리를 포함하도록하는 것입니다. 당신은 컬렉션으로 사용할 수있는 모든 구현을 주입하고 (즉, 당신이 필요하다면, 또는 그 이상)의 적용 것들을 하나를 찾을 그들을 반복 할 수 있습니다 :
이보다 쿨러 솔루션은 구현 자체가 그들이 적용 할 수 있는지 확인하기 위해 논리를 포함하도록하는 것입니다. 당신은 컬렉션으로 사용할 수있는 모든 구현을 주입하고 (즉, 당신이 필요하다면, 또는 그 이상)의 적용 것들을 하나를 찾을 그들을 반복 할 수 있습니다 :
public interface BaseInterface { boolean canHandle(Object parameter); Object doTheWork(Object parameter); } @Service public class SomeService { private final BaseInterface[] implementations; // Spring injects all beans implementing BaseInterface public MessageService(BaseInterface... implementations) { this.implementations = implementations; } public Object doSomething(Object parameter) { BaseInterface baseInterface = findBaseInterface(parameter); return baseInterface.doTheWork(parameter); } private BaseInterface findBaseInterface(Object parameter) { return Arrays.stream(implementations) .findAny(i -> i.canHandle(parameter) .orElseThrow(new MyRuntimeException(String.format("Could not find BaseInterface to handle %s", parameter))); } }
-
==============================
5.그것은 바로 인터페이스가 하나 개 이상의 클래스에 의해 구현되는 이러한 경우에 우리가 @Component를 사용하는 콩의 각 이름을 가지고 여기에 대답하고있다 (이름 = $ beanName에)
그것은 바로 인터페이스가 하나 개 이상의 클래스에 의해 구현되는 이러한 경우에 우리가 @Component를 사용하는 콩의 각 이름을 가지고 여기에 대답하고있다 (이름 = $ beanName에)
나는 그런 경우에 봄도지도에 같은 콩을 autowire하기 수있는 또 하나 개의 지점을 추가하고 싶습니다 :
@Autowired Map<String,InterfaceName> interfaceMap; //this will generate beans and index them with beanName as key of map
from https://stackoverflow.com/questions/37565186/spring-couldnt-autowired-there-is-more-than-one-bean-of-type by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 어떻게 UTC 시간대에 봄 부팅 JVM을 강요하는 걸까? (0) | 2019.10.22 |
---|---|
[SPRING] 자바 - 봄 WS -로드 상대는 XSD 파일에 포함 (톰캣 8) (0) | 2019.10.21 |
[SPRING] 재귀 thymeleaf 사용하여 메뉴를 렌더링하는 방법 (0) | 2019.10.18 |
[SPRING] 파라미터 화 된 형태를 선택할 수 없습니다 (0) | 2019.10.18 |
[SPRING] 자신감 문서에 대한 문자열에 @ApiModelProperty 데이터 유형을 설정하는 방법 (0) | 2019.10.18 |