Skip to content

BeanFactoryPostProcessor

tylertreat edited this page Dec 31, 2012 · 3 revisions

The BeanFactoryPostProcessor interface allows modifications to be made to an InfinitumContext's bean definitions by exposing its BeanFactory. The interface has but a single method which must be implemented, postProcessBeanFactory, which can be used to modify the context's BeanFactory after it has been initialized. This is useful for targeting environments which require different components. For example, if a component implementation only supports a particular set of devices or API levels, it could be overridden using a BeanFactoryPostProcessor which supplies an alternate implementation. This moves the code needed to swap implementations away from any application/business logic and allows Infinitum to handle an application's configuration.

BeanFactoryPostProcessors are specialized beans. As such, they can be registered with an InfinitumContext using normal means, either through XML or with annotations (if component scanning is enabled). They are not eligible for autowiring; however, they themselves can be autowire candidates.

Each post processor's postProcessBeanFactory method is executed immediately after context initialization. Thus, registering a bean with a name that already exists in the BeanFactory will overwrite the previously initialized bean.

Example Implementations

Creating a BeanFactoryPostProcessor is simply a matter of implementing the interface and registering it with the InfinitumContext. The Component annotation will allow the post processor to be picked up and registered automatically by the framework. The below example shows how a BeanFactoryPostProcessor might be implemented to accomplish build-specific configurations.

@Component
public class BuildTargetedPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(BeanFactory beanFactory) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
            // Configure beans for newer APIs
        } else {
            // Configure beans for older APIs
        }
    }

}

If you are not using component scanning, you can register this post processor in the infinitum.cfg.xml:

<bean id="buildTargetedPostProcessor"
    class="com.foo.bar.postprocessor.BuildTargetedPostProcessor" />

BeanFactoryPostProcessor vs. BeanProvider

Both BeanFactoryPostProcessors and BeanProviders can be used to programmatically register beans with the BeanFactory during framework initialization. As shown above, BeanFactoryPostProcessor directly exposes the BeanFactory, while BeanProvider can be implemented to return a list of beans which the framework will register.

Both can be used to register beans, but there is a key distinction in how these two hooks work. As its name implies, a BeanFactoryPostProcessor is executed after the BeanFactory has been initialized and beans have been registered. What's less obvious is that BeanFactoryPostProcessors are executed after BeanPostProcessors, meaning any beans registered through a BeanFactoryPostProcessor will not undergo bean post processing. This has an important implication in that autowired dependency injections are identified during this step, so beans registered through a BeanFactoryPostProcessor are not eligible for autowiring.

BeanProviders, on the other hand, are used to programmatically define beans for registration which will undergo post processing. BeanProvider beans are registered before post processors are executed.

Clone this wiki locally