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.
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.
source to share
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;
}
}
source to share