No unique bean defined: expected single bean match, but 2 found

I get the following exception when I deploy 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 Normal, the second is the Adapter, and the third is Service. The adapter is dependent on Common and Service is dependent on the adapter. All three maven projects. Now in my general project I have an interface called CommonAdapter.java

  public interface CommonAdapter { List service() ; } 

I have an AdapterFactory.java class in the same project (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> 

Now in my adapter project I have implementation classes for CommonAdapter.java One of them is EndecaAdapetr.java and the other is 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, you want to call a service method from the above two classes based on input.

 public class ProductSearchServiceImpl { @Autowired private AdapterFactory adapterFactory; public Search searchProducts(){ Adapter endecaAdapter = this.adapterFactory .getAdapter("endeca "); } } 
+7
java spring javabeans
source share
4 answers

@Autowired only works when there is no doubt about which container-managed instance should be injected. In principle, this can be achieved (at least) in three ways:

  • There is only one container-managed bean, which is an IS-A self-defined declared field type;
  • There are more container-managed beans that check the above IS-A condition, but the auto-detect field is also qualified (in Spring using the @Qualifier annotation)
  • You are not using @Autowired , but rather enter beans by name.

In your case, you have two beans that check the IS-A condition:

endeca IS-A Adapter

and

solar IS-A Adapter .

Thus, the container does not have a unique candidate for self-timer, so it fails to configure.

+11
source share

Use @Primary and @Resource if you have multiple implementation classes.

 @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 enter as:

 @Resource("solar") Adapter solarAdapter; 
+7
source share

There is another standard JPA solution: you can use @named and @inject, so the example would be like this:

 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 look like this:

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

You do not need, put a name, Spring do it yourself :)

+1
source share

Already allowed here .

You must add the component using @javax.annotation.Resource(name="componentName") .

-one
source share

All Articles