【问题标题】:No unique bean of type is defined: expected single matching bean but found 2 [duplicate]没有定义唯一的 bean 类型:预期的单个匹配 bean 但找到 2 [重复]
【发布时间】:2023-03-06 07:44:01
【问题描述】:

我在部署代码时遇到以下异常

 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

我有 3 个不同的项目,一个是 Common,第二个是 Adapter,第三个是 Service。 适配器依赖于 Common,Service 依赖于 Adapter。这三个都是 Maven 项目。 现在在我的 Common 项目中,我有一个名为 CommonAdapter.java 的接口

 public interface CommonAdapter {
    List service() ;
}

我在同一个项目中有一个名为 AdapterFactory.java 的类(即 Common)

@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>

现在在我的适配器项目中,我有 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
    }
}

现在在我的Service项目中,想根据输入调用上述两个类的service方法。

public class ProductSearchServiceImpl {
    @Autowired
    private AdapterFactory adapterFactory;
    public Search searchProducts(){
    Adapter endecaAdapter = this.adapterFactory
                .getAdapter("endeca ");
 }
 }

【问题讨论】:

  • Bean 名称在所有配置中应该是唯一的。很明显,没有为 com.belk.api.adapter.contract.Adapter 找到唯一的 bean。所以再次检查你的 bean 定义。

标签: java spring javabeans


【解决方案1】:

@Autowired 仅在毫无疑问应该注入哪个容器管理的实例时才有效。基本上,这可以通过(至少)3 种方式实现:

  1. 只有一个容器管理的 bean 是 IS-A 声明的自动装配字段类型;
  2. 有更多容器管理的 bean 可以验证上述 IS-A 条件,但自动装配字段也是合格的(在 Spring 中,通过使用 @Qualifier 注释)
  3. 您不使用@Autowired,而是按名称注入bean。

在您的情况下,您有两个验证 IS-A 条件的 bean:

endecaIS-A Adapter

solarIS-A Adapter.

因此容器没有唯一的自动装配候选者,因此它在设置自身时崩溃。

【讨论】:

    【解决方案2】:

    当您有多个实现类时,使用@Primary@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
        }
    }
    

    然后像这样注入:

    @Resource("solar")
    Adapter solarAdapter;
    

    【讨论】:

    • @Primary @Component@Autowired 在 @Qualifier 没有的情况下成功了。
    【解决方案3】:

    还有另一个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
        }
    }
    

    Inject 会是这样的:

    @Inject @Named("SolarAdapter")
    Adapter solarAdapter;
    

    你不需要,输入名字,Spring自己做:)

    【讨论】:

      【解决方案4】:

      已经解决here

      您必须使用@javax.annotation.Resource(name="componentName") 注入组件。

      【讨论】:

      • 这个问题然后被标记为提到的链接的副本,而不是作为答案发布。
      猜你喜欢
      • 2014-02-10
      • 2016-05-09
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多