Spring FactoryBean and autowiring not working : expected single matching bean but found 2

19,932

Solution 1

In the end, I solved my problem by changing the name of the factoryBean to match the name of the injected field, and by removing one entry in the scanning of the project. (Could it be that the "double scanning" was causing trouble ?)

<context:component-scan base-package="dispensation.**.factory.**,dispensation.**.metier.factory.**

=>

<context:component-scan base-package="dispensation.**.factory.**

@Service("interfaceAutomateMetierService")
public class InterfaceAutomateServiceFactory implements FactoryBean<IInterfaceAutomateMetierService> {

@Service
public class AnalysePreparationGlobaleMetierService implements IAnalysePreparationGlobaleMetierService {

  @Autowired
  private IInterfaceAutomateMetierService interfaceAutomateMetierService;

Solution 2

Instead of

@Autowired
@Qualifier("interfaceAutomateServiceFactory")
private IInterfaceAutomateMetierService interfaceAutomateMetierService;

try this

@Resource(name="interfaceAutomateServiceFactory")
private IInterfaceAutomateMetierService interfaceAutomateMetierService;

Solution 3

Using @Primary annotation with your bean(one of them from the two) can solve the issue.The Question however still remains as to why the @Resource annotation for Spring is unable to distinguish based on Autowiring.

Reference "Autowiring two beans implementing same interface - how to set default bean to autowire?"

Share:
19,932
Fab313
Author by

Fab313

-

Updated on June 04, 2022

Comments

  • Fab313
    Fab313 about 2 years

    I have two classes, each one autowiring the same class through a factory :

    @Service
    public class AnalyseDispensationNominativeMetierService implements IAnalyseDispensationNominativeMetierService {
    
      @Autowired
      @Qualifier("interfaceAutomateServiceFactory")
      private IInterfaceAutomateMetierService interfaceAutomateMetierService;
      [...]
    
    
    @Service
    public class AnalysePreparationGlobaleMetierService implements IAnalysePreparationGlobaleMetierService {
    
      @Autowired
      @Qualifier("interfaceAutomateServiceFactory")
      private IInterfaceAutomateMetierService interfaceAutomateMetierService;
      [...]
    

    The object I want to create through the factory :

    @Service
    public class InterfaceAutomate implements IInterfaceAutomateMetierService {
    [...]
    

    The factory :

    @Service("interfaceAutomateServiceFactory")
    public class InterfaceAutomateServiceFactory implements FactoryBean<IInterfaceAutomateMetierService> {
    
      @Autowired(required = true)
      private InterfaceAutomate ijinInterfaceAutomate;
    
      @Override
      public IInterfaceAutomateMetierService getObject() {
        return ijinInterfaceAutomate;
      }
    
      @Override
      public Class<?> getObjectType() {
        return IInterfaceAutomateMetierService.class;
      }
    
      @Override
      public boolean isSingleton() {
        return false;
      }
    

    I keep getting the following error, even though I'm using qualifier annotation... Any idea on what I'm doing wrong ? :

    No unique bean of type [IInterfaceAutomateMetierService] is defined: expected single matching bean but found 2: [interfaceAutomate, interfaceAutomateServiceFactory]
    

    Complete stack trace

    GRAVE: Exception lors de l'envoi de l'évènement contexte initialisé (context initialized) à l'instance de classe d'écoute (listener) org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'analysePreparationGlobaleMetierService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dispensation.commun.service.metier.IInterfaceAutomateMetierService dispensation.analysePreparationGlobale.service.metier.impl.AnalysePreparationGlobaleMetierService.interfaceAutomateMetierService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [dispensation.commun.service.metier.IInterfaceAutomateMetierService] is defined: expected single matching bean but found 2: [interfaceAutomate, interfaceAutomateServiceFactory]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:388)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
        at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dispensation.commun.service.metier.IInterfaceAutomateMetierService dispensation.analysePreparationGlobale.service.metier.impl.AnalysePreparationGlobaleMetierService.interfaceAutomateMetierService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [dispensation.commun.service.metier.IInterfaceAutomateMetierService] is defined: expected single matching bean but found 2: [interfaceAutomate, interfaceAutomateServiceFactory]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
        ... 20 more
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [dispensation.commun.service.metier.IInterfaceAutomateMetierService] is defined: expected single matching bean but found 2: [interfaceAutomate, interfaceAutomateServiceFactory]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:823)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485)
        ... 22 more