Search This Blog

Thursday 26 April 2012

Using BeanPostProcessors

Spring provides us with BeanPostProcessor classes that can be used to process beans before and after they have been configured by the container.
Consider the below BeanPostProcessor:
public class CarProcessor implements BeanPostProcessor {

    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof ICar) {
            System.out.println("postProcessAfterInitialization: Car custom initialization was complete  -  ["
                    + beanName + "]");
        } else {
            System.out.println("postProcessAfterInitialization: non car object " + beanName);
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof ICar) {
            System.out.println("postProcessBeforeInitialization: Car's custom init methods not called yet -  ["
                    + beanName + "]");
        } else {
            System.out.println("postProcessBeforeInitialization: non car object " + beanName);
        }
        return bean;
    }

}
As seen in the above class, the BeanPostProcessor exposes two methods. The postProcessBeforeInitialization() method is called after the bean has been created and its properties set by the Container. The method takes the bean object and the bean name as parameters. The return type of the method is not void, but an object. This means that the method does not have to return the bean. It is free to wrap the bean instance in a proxy class and return the wrapper instead.
The other method  postProcessAfterInitialization() is called by the container after the custom init methods have been executed. It also has the return type of an object.
I decided to test the code on the Car class from the previous example:
<bean id="car1" class="com.car.CustomInitDestroyCar" autowire="byName"/>
<bean id="combustEngine" class="com.car.Engine" p:name="Combusto" />
The main method for testing the above beans is
public static void main(String[] args) {
    XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("default-init-destroy-beans.xml"));
    beanFactory.addBeanPostProcessor(new CarProcessor());
    CustomInitDestroyCar car1 = (CustomInitDestroyCar) beanFactory.getBean("car1");
    System.out.println(car1.describe());
    beanFactory.destroyBean("car1",car1);
}
The BeanPostProcessor is added to the BeanFactory. The output is as below:
Creating object
postProcessBeforeInitialization: non car object combustEngine
postProcessAfterInitialization: non car object combustEngine
Setting the properties
postProcessBeforeInitialization: Car's custom init methods not called yet -  [car1]
Checking if engine is fine
postProcessAfterInitialization: Car custom initialization was complete  -  [car1]
Car in use com.car.CustomInitDestroyCar@2bb514, engine is Engine - com.car.Engine@17d5d2a and name Combusto
Cleaning the car after use
I retained my default init and destroy methods from the previous post. As can be seen the postProcessBeforeInitialization was called before the custom init method, while the postProcessAfterInitialization was called after it.

No comments:

Post a Comment