java - Spring @Bean autowire() - 第二次失败(?)

标签 java spring dependency-injection autowired

好吧,我有一个创建两个 bean 的配置类。它们的定义如下:

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;
    }
}

如果我在两个实例中都放置断点,流程如下:

1) fileUploadPaths 已实例化,对我来说它看起来是正确的。

2) fileService 被实例化,但是通过 FileUploadConfiguration bean 创建的 postProcessPropertyValues .. 这对我来说似乎很奇怪。 enter image description here

3)之后,我得到一个异常,因为Spring似乎尝试再次创建fileService,但现在通过createBean,并且出于某种原因@Qualifier关于参数定义似乎被忽略了。

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fileService' defined in class x.y.z.FileUploadConfiguration: Unsatisfied dependency expressed through constructor argument with index 0 of type [a.b.c.PrefixedPropertyFactoryBean]: Ambiguous factory method argument types - did you specify 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.java:464) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) at 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(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)

注意:如果我将 fileService 定义更改为以下内容,此问题即可修复:

@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;
}

因此,我不是让 Spring 通过 @Bean(autowire = Autowire.BY_TYPE) Autowiring 我的 bean,而是简单地 Autowiring AutowireCapableBeanFactory 并 Autowiring CRUDFileService我自己。

我的问题是:为什么会发生这种行为?我是否正确使用了@Bean(autowire = Autowire.BY_TYPE)?我以前就这样使用过它,它的工作方式非常神奇,只是我没有像使用这个那样 Autowiring bean 方法参数。

最佳答案

我看到的问题是您正在尝试将 Spring FactoryBean 作为依赖项注入(inject)到另一个 bean 中。 FactoryBean 不过很特殊,它是一个 bean 工厂,生成的 bean 就是您应该注入(inject)到其他对象中的内容。

因此,假设您在 CRUDFileService 中的依赖项是 Properties 类而不是 FactoryBean,如果您要尝试此操作,它应该可以正常工作:

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;
    }
}

关于java - Spring @Bean autowire() - 第二次失败(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30896557/

相关文章:

java - Spring Data JPA 何时实际调用数据库上的 INSERT?

java - 使用 SwingWorker 在 JTextPane 中突出显示语法

java - 简单的日期格式格式不正确

java - 如何连接三张 table ?

java - 如何从 Tapestry BeanEditForms 获取数据?

Java:Spring:如何动态地将参数传递给构造函数?

dependency-injection - 依赖注入(inject)框架 : Why do I care?

java - 带有 Hibernate 和 Spring 的通用 DAO,是不是比这更好的方法?

scala - 使用 Scala Guice 将特征绑定(bind)到对象

java - 反序列化对象列表