web-dev-qa-db-ja.com

タイプの一意のBeanが定義されていません:単一の一致するBeanが必要ですが、2が見つかりました

コードをデプロイすると、以下の例外が発生します

 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つの異なるプロジェクトがあります。1つは共通、2つ目はアダプター、3つ目はサービスです。アダプターはCommonに依存し、ServiceはAdapterに依存します。 3つはすべて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の実装クラスがあります。1つはEndecaAdapetr.Javaで、もう1つは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プロジェクトで、入力に基づいて上記の2つのクラスのserviceメソッドを呼び出したいと思います。

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

@Autowiredは、どのコンテナー管理インスタンスを注入する必要があるかが疑わしい場合にのみ機能します。基本的に、これは(少なくとも)3つの方法で達成できます。

  1. 自動配線フィールドのIS-A宣言タイプであるコンテナ管理Beanは1つだけです。
  2. 上記のIS-A条件を検証するコンテナー管理Beanは他にもありますが、自動配線フィールドも修飾されます(Springでは、@Qualifierアノテーションを使用して)
  3. @Autowiredを使用せず、名前でBeanを注入します。

あなたの場合、IS-A条件を検証する2つのBeanがあります。

endeca IS-A Adapter

そして

solar IS-A Adapter

そのため、コンテナには一意の自動配線候補がないため、コンテナ自体のセットアップ中にクラッシュします。

11
Andrei Nicusan

使用する @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;
8
Abhishek Nayak

別の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 @Named("SolarAdapter")
Adapter solarAdapter;

あなたは必要ありません、名前を付けてください、春は自分でそれをします:)

1
Seba Echarte