Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 495
Fab313 Avatar asked Feb 13 '23 15:02

Fab313


2 Answers

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;
like image 63
Fab313 Avatar answered Feb 15 '23 07:02

Fab313


Instead of

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

try this

@Resource(name="interfaceAutomateServiceFactory")
private IInterfaceAutomateMetierService interfaceAutomateMetierService;
like image 31
Andrei Stefan Avatar answered Feb 15 '23 08:02

Andrei Stefan