Java 未定义唯一类型的 bean:预期单个匹配 bean,但发现 2
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22300102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
No unique bean of type is defined: expected single matching bean but found 2
提问by user2334926
I am getting the below exception when I am deploying the code
部署代码时出现以下异常
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.belk.api.adapter.contract.Adapter] is defined: expected single matching bean but found 2: [endeca, solar]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
... 64 more
I have 3 different projects one is Common, second is Adapter and the third is Service. The adapter is dependent on Common and Service is dependent on Adapter. All three are maven projects. Now in my Common project I have an interface called CommonAdapter.java
我有 3 个不同的项目,一个是 Common,第二个是 Adapter,第三个是 Service。适配器依赖于 Common,而 Service 依赖于 Adapter。这三个都是maven项目。现在在我的 Common 项目中,我有一个名为 CommonAdapter.java 的接口
public interface CommonAdapter {
List service() ;
}
I have a class called AdapterFactory.java in the same project (i,e Common)
我在同一个项目中有一个名为 AdapterFactory.java 的类(即通用)
@Component
public class AdapterFactory {
@Autowired
Adapter adapter;
public Adapter getAdapter(String adapterName){
return adapter;
}
}
<context:component-scan base-package="com.test.api" />
<bean
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"
id="adapterFactory">
<property name="serviceLocatorInterface" value="com.test.api.adapter.manager.AdapterFactory">
</property>
</bean>
Now in my Adapter Project, I have the implementation classes for CommonAdapter.java One is EndecaAdapetr.java and the other is SolarAdapter.java
现在在我的适配器项目中,我有 CommonAdapter.java 的实现类,一个是 EndecaAdapetr.java,另一个是 SolarAdapter.java
@Component("endeca")
public class EndecaAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
@Component("solar")
public class SolarAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
Now in my Service project, want to invoke the service method of the above two classes based on the input.
现在在我的Service项目中,想根据输入调用上面两个类的service方法。
public class ProductSearchServiceImpl {
@Autowired
private AdapterFactory adapterFactory;
public Search searchProducts(){
Adapter endecaAdapter = this.adapterFactory
.getAdapter("endeca ");
}
}
回答by Andrei Nicusan
@Autowired
works only when there is no doubt on which container-managed instance should be injected. Basically, this can be attained in (at least) 3 ways:
@Autowired
仅当毫无疑问应该注入哪个容器管理的实例时才有效。基本上,这可以通过(至少)三种方式实现:
- There is only one container-managed bean that IS-A declared type of the autowired field;
- There are more container-managed beans that validate the above IS-A condition, but the autowired field is also qualified (in Spring, by using a
@Qualifier
annotation) - You don't use
@Autowired
, but rather inject the beans by name.
- 只有一个容器管理的 bean 是自动装配字段的 IS-A 声明类型;
- 有更多容器管理的 bean 可以验证上述 IS-A 条件,但自动装配的字段也是限定的(在 Spring 中,通过使用
@Qualifier
注释) - 您不使用
@Autowired
,而是按名称注入 bean。
In your case, you have two beans that validate the IS-A condition:
在您的情况下,您有两个可验证 IS-A 条件的 bean:
endeca
IS-A Adapter
endeca
IS-A Adapter
and
和
solar
IS-A Adapter
.
solar
是-A Adapter
。
So the container does not have a unique autowire candidate, therefore it crashes while setting up itself.
所以容器没有唯一的自动装配候选者,因此它在设置自身时崩溃。
回答by Abhishek Nayak
Use @Primary
and @Resource
when you have multiple implementation classes.
当您有多个实现类时使用@Primary
and @Resource
。
@Primary
@Component("endeca")
public class EndecaAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
@Component("solar")
public class SolarAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
and inject like:
并注入:
@Resource("solar")
Adapter solarAdapter;
回答by Seba Echarte
There are another JPA standard solution: You can use @named and @inject, so the example will be like this:
还有另一种 JPA 标准解决方案:您可以使用 @named 和 @inject,因此示例将如下所示:
public iterface Adapter {
}
@Named
public class EndecaAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
@Named
public class SolarAdapter implements Adapter {
List service() {
// My bussiness logic
}
}
and Inject will be like this:
和注入将是这样的:
@Inject @Named("SolarAdapter")
Adapter solarAdapter;
You don't need, put name, Spring do it by herself :)
你不需要,输入名字,Spring 自己做 :)