没有定义类型的唯一bean:期望的单个匹配bean但找到2

时间:2014-03-10 12:26:42

标签: java spring javabeans

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

 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的类(i,e 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>

现在在我的Adapter Project中,我有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项目中,想要根据输入调用上述两个类的服务方法。

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

4 个答案:

答案 0 :(得分:11)

只有在毫无疑问应该注入哪个容器管理的实例时,

@Autowired才有效。基本上,这可以通过(至少)3种方式实现:

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

    endeca IS-A Adapter

    solar IS-A Adapter

    因此容器没有唯一的autowire候选者,因此在设置时会崩溃。

答案 1 :(得分:8)

如果您有多个实施类,请使用@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;

答案 2 :(得分:1)

还有另一个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自己做:)

答案 3 :(得分:-1)

已经解决here

您必须使用public static void Business(){ System.out.println("Hi Harry"); 注入组件。