Spring @Bean autowire () - cannot execute second (?) Time

So I have a config class that creates two beans. They are defined as follows:

public class FileUploadConfiguration {

    public static final String UPLOAD_PREFIX = "file.upload";

    @Bean(name = "fileService", autowire = Autowire.BY_TYPE)
    @DependsOn("fileUploadPaths")
    @Autowired
    public CRUDFileService fileService(@Qualifier("fileUploadPaths") PrefixedPropertyFactoryBean fileUploadPaths) throws Exception {
        Map<String, String> paths = Maps.fromProperties(fileUploadPaths.getObject());
        return new CRUDFileService(File.class.getName(), paths);
    }

    @Bean(name = "fileUploadPaths")
    public PrefixedPropertyFactoryBean fileUploadPaths(Environment environment) {
        PrefixedPropertyFactoryBean fileUploadPaths = new PrefixedPropertyFactoryBean();
        fileUploadPaths.setPrefix(UPLOAD_PREFIX);
        fileUploadPaths.setLocations(ResourceUtils.getActiveResources(environment));
        return fileUploadPaths;
    }
}

      

If I set breakpoints on both instances, the flow is as follows:

1) fileUploadPaths is created and it looks correct to me.

2) FileService receives a copy, but a postProcessPropertyValues create FileUploadConfiguration the bean .. it seems strange to me. enter image description here

3) After that I get an exception because it seems that Spring is trying to create the fileService again , but now via createBean , and by whatever the @Qualifier by the parameter definition seems to be ignored.

Exception on thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: An error occurred while creating a bean named 'fileService' defined in class xyzFileUploadConfiguration: Unsatisfied dependency expressed via constructor argument with index 0 of type [abcPrefixedProperty] ambiguous argument factoryfixedPropertyFactory have you specified the correct bean references as factory method arguments? at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray (ConstructorResolver.java:735) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod (ConstructorResolver) .support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod (AbstractAutowireCapableBeanFactory.java:1119) in org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance (AbstractAutowireCapableBeanFactory.java:1014) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.AbstractAutowireCapableBeanFactory. AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:476) in org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject (AbstractBeanFactory.java:303) in org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java : 230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:299) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBean :Factory.getBean194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:755) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactory.AbstractApplicationContext.finishBeanFactory .AbstractApplicationContext.refresh (AbstractApplicationContext.java:480) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:118)refresh (AbstractApplicationContext.java:480) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:118)refresh (AbstractApplicationContext.java:480) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:118)

NOTE. ... This was fixed if I changed the definition of fileService to the following:

@Bean(name = "fileService")
@DependsOn("fileUploadPaths")
@Autowired
public CRUDFileService fileService(@Qualifier("fileUploadPaths") PrefixedPropertyFactoryBean fileUploadPaths, AutowireCapableBeanFactory factory) throws Exception {
    Map<String, String> paths = Maps.fromProperties(fileUploadPaths.getObject());
    CRUDFileService crudFileService = new CRUDFileService(File.class.getName(), paths);
    factory.autowireBean(crudFileService);
    return crudFileService;
}

      

So instead of Spring autowire my bean via @Bean (autowire = Autowire.BY_TYPE) , I just autowire AutowireCapableBeanFactory and autowire CRUDFileService bean.

My question is, why is this behavior happening? Am I using @Bean (autowire = Autowire.BY_TYPE) correctly? I've used it before and it worked like a charm, except I didn't autowire the bean method parameters like I did with this.

+3


source to share


1 answer


The problem I see is that you are trying to inject Spring FactoryBean

as a dependency in another bean. FactoryBean

is special though it is a factory for a bean and the resulting bean is what you should inject into other objects.

Suppose your dependency in CRUDFileService

is a class Properties

instead of FactoryBean, if you want to try this it should work cleanly:



public class FileUploadConfiguration {

    public static final String UPLOAD_PREFIX = "file.upload";

    @Bean(name = "fileService", autowire = Autowire.BY_TYPE)
    @Autowired
    public CRUDFileService fileService(@Qualifier("fileUploadPaths") Properties fileUploadPaths) throws Exception {
        Map<String, String> paths = Maps.fromProperties(fileUploadPaths);
        return new CRUDFileService(File.class.getName(), paths);
    }

    @Bean(name = "fileUploadPaths")
    public PrefixedPropertyFactoryBean fileUploadPaths(Environment environment) {
        PrefixedPropertyFactoryBean fileUploadPaths = new PrefixedPropertyFactoryBean();
        fileUploadPaths.setPrefix(UPLOAD_PREFIX);
        fileUploadPaths.setLocations(ResourceUtils.getActiveResources(environment));
        return fileUploadPaths;
    }
}

      

0


source







All Articles