Skip to content

FactoryBeans with @Autowired constructors are incompatible with @EnableConfigurationProperties #1315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Stummi opened this issue Jul 30, 2014 · 1 comment

Comments

@Stummi
Copy link
Contributor

Stummi commented Jul 30, 2014

Hi,

Using spring-boot-starter-web, autowiring into the constructor of a FactoryBean does not work:
https://gist.github.com/Stummi/f9ae02ffe63be0d0d5de

when using spring-boot-starter instead of spring-boot-starter-web (and removing the controller) this autowiring works.

Kind Regards,
Michael Stummvoll

@Stummi Stummi changed the title actoryBean-Constructor Autowiring not working with spring-boot-starter-web FactoryBean-Constructor Autowiring not working with spring-boot-starter-web Jul 30, 2014
@wilkinsona
Copy link
Member

It's always a risk trying to autowire dependencies into a FactoryBean. For example, it's sometimes necessary to instantiate a FactoryBean to determine if the type that it creates can satisfy another autowired dependency. If the FactoryBean's own dependencies also require autowiring then things can break. To avoid problems like this, I'd recommend not autowiring dependencies into a factory bean's constructor.

In this particular case, the spring-boot-starter-web dependency enables configuration properties which means that ConfigurationPropertiesBindingPostProcessor is registered in the application context. It makes a call to this.beanFactory.getBean(PropertySourcesPlaceholderConfigurer.class) which causes the failed attempt to instantiate the factory bean. If you use spring-boot-starter instead then no configuration properties are enabled and, therefore, the post-processor isn't there so you don't see the failure.

The problem can be reproduced with a dependency on spring-boot-starter if the application enables configuration properties:

package org.springframework.boot.issues.gh1315;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

@ComponentScan
@EnableAutoConfiguration
@EnableConfigurationProperties
public class Main {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Component
    public static class TestFactory implements FactoryBean<Test> {

        private ResourcePatternResolver resolver;

        @Autowired
        public TestFactory(ResourcePatternResolver resolver) {
            this.resolver = resolver;
        }

        @Override
        public Test getObject() throws Exception {
            return new Test();
        }

        @Override
        public Class<Test> getObjectType() {
            return Test.class;
        }

        @Override
        public boolean isSingleton() {
            return true;
        }
    }

    public static class Test {

    }   
}

I've added this code to the Spring Boot issues repository.

To work around this limitation, if you really want to use autowiring with your FactoryBean, you could autowire a setter method or field. Alternatively, and this is what I recommend, you could remove the @Autowired and @Component annotations and create the FactoryBean in Java configuration instead:

@Bean
public TestFactory test(ResourcePatternResolver resolver) {
    return new TestFactory(resolver);
}

@wilkinsona wilkinsona changed the title FactoryBean-Constructor Autowiring not working with spring-boot-starter-web FactoryBeans with @Autowired constructors are incompatible with @EnableConfigurationProperties Jul 30, 2014
@dsyer dsyer closed this as completed Aug 5, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants