@Configurable does not work for objects initialized in @PostConstruct methods

I am using Spring with AspectJ via compilation in time to use @Configurable Spring annotation for non container managed objects.

Here's an example of a @ Custom-annotated object:

@Configurable(autowire = Autowire.BY_TYPE)
public class TestConfigurable {

    private TestComponent component;

    public TestComponent getComponent() {
        return component;
    }

    @Autowired
    public void setComponent(TestComponent component) {
        this.component = component;
    }
}

      

The component I am inserting into this object:

@Component
public class TestComponent {}

      

When I create the TestConfigurable after the context has been created, the TestComponent is injected there fine, but when I do it from a @ PostConstruct annotated method, it doesn't autoset.

Component with @PostConstruct:

@Component
public class TestPostConstruct {

    @PostConstruct
    public void initialize() {
        TestConfigurable configurable = new TestConfigurable();
        System.out.println("In post construct: " + configurable.getComponent());
    }
}

      

Application I am running:

public class TestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
        applicationContext.registerShutdownHook();

        TestConfigurable configurable = new TestConfigurable();
        System.out.println("After context is loaded: " + configurable.getComponent());
    }
}

      

Here is the output this application produces:

In post construct: null
After context is loaded: paulenka.aleh.roguelike.sandbox.TestComponent@fe18270

      

So, is there any workaround for dependency injection into @Configurable objects that are created inside @PostConstruct methods? All @Component-annotated beans are already in context, and auto-connect is already done for them when @PostConstruct is called. Why doesn't Spring autowiring work here? ..

Other configuration files (context and pom.xml) can be sent if they help resolve the issue.

Update 1: Looks like I found the cause of the problem. Objects annotated with @Configurable are initialized with AnnotationBeanConfigurerAspect, which implements BeanFactoryAware. This aspect uses the BeanFactory to initialize the beans. It looks like the @PostConstruct method of the TestPostConstruct object is executed before the BeanFactory is set to AnnotationBeanConfigurerAspect. If the logger is installed for debugging, the following message is displayed on the console: "BeanFactory not installed ...: make sure this configurator is running in a Spring container. Cannot configure bean of type [...]. Continue without injection."

The question, if there is any workaround, is still open to me ...

+3


source to share


1 answer


I found one workaround. To initialize the AnnotationBeanConfigurerAspect before @PostConstruct is executed, you can add the following annotation to the class with this @PostConstruct method:

@DependsOn("org.springframework.context.config.internalBeanConfigurerAspect")

      



Hope this information is helpful for someone.

+4


source







All Articles