Question

I am trying to write a service-oriented application.

I have a been called memory defined as such:

package com.example.assets;

//imports ignored

@Resource
public class Memory {
}

And I have a service been called memoryHandler defined as such:

package com.example.service;

//imports ignored

@Service
public class MemoryHandler {

    @Autowired
    private Memory memory;

    public void execute() {
        //do something with memory
    }
}

There is also another class, which is a BeanFactoryPostProcessor:

package com.example.service;

//imports ignored

@Component
public class PostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.getBeansOfType(MemoryHandler.class, false, true);
    }
}

Which prematurely looks up the bean, memoryHandler, leaving it instantiated` but not autowired. However, I want the bean to be autowired before it is fetched by the factory.

In my Main class I have written:

package com.example.service;

//imports ignored

public class Main {

    public static void main(String[] args) {
        final ApplicationContext context = new ClassPathXmlApplicationContext("/context.xml");
        context.getBean(MemoryHandler.class).execute();
    }

}

I get a NullPointerException on the line I work with the memory. I replaced the above declaration with a setter injection, and upon tracing realized that the injection never occurs.

I have changed the annotations on both components to Service, Repository, and Component and also have tried replacing Autowired with Resource to no avail.

What am I missing here? I have read all the questions that have shown up in my search for an answer, and none of them helps me (I got the tip about using Resouce annotations there).

Needless to say, I have not missed annotation configuration for my beans:

<context:annotation-config/>
<context:component-scan base-package="com.example"/>

Moreover, autowiring works just fine when autowired beans are defined in the XML configuration file, and not via annotations.

I am using Spring 3.2.3.RELEASE.

Was it helpful?

Solution

Changing the implementation of the PostProcessor is the key:

Instead of:

public class PostProcessor implements BeanFactoryPostProcessor {

I will have to write:

public class PostProcessor implements ApplicationContextAware {

This ensures that the context will be fully populated before it is post-processed, which in my case works just fine. But I am wondering if there is another way to do this, using the usual BeanFactoryPostProcessor interface?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top