What is the difference between BeanPostProcessor and init/destroy method in Spring?

Spring

Spring Problem Overview


What is the difference between implementing the BeanPostProcessor interface and either using the init/destroy method attributes in the XML configuration file in Spring or implementing InitializingBean/DisposableBean interface?

Spring Solutions


Solution 1 - Spring

This is pretty clearly explained in the Spring documentation about the Container Extension Points.

> The BeanPostProcessor interface defines callback methods that you can > implement to provide your own (or override the container's default) > instantiation logic, dependency-resolution logic, and so forth. If you > want to implement some custom logic after the Spring container > finishes instantiating, configuring, and initializing a bean, you can > plug in one or more BeanPostProcessor implementations.

So in essence the method postProcessBeforeInitialization defined in the BeanPostProcessor gets called (as the name indicates) before the initialization of beans and likewise the postProcessAfterInitialization gets called after the initialization of the bean.

The difference to the @PostConstruct, InitializingBean and custom init method is that these are defined on the bean itself. Their ordering can be found in the Combining lifecycle mechanisms section of the spring documentation.

So basically the BeanPostProcessor can be used to do custom instantiation logic for several beans wheras the others are defined on a per bean basis.

Solution 2 - Spring

Above answers clearly explains some of the very important aspect.

Apart from that it's also important to understand that both beanPostProcessor and init and destroy methods are part of the Spring bean life cycle.

BeanPostProcessor class has two methods.

  1. postProcessBeforeInitialization - as name clearly says that it's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.

  2. postProcessAfterInitialization - any thing that you want to do after initialization before bean reference is given to application.

Sequence of the questioned methods in life cycle as follows :

  1. BeanPostProcessor.postProcessBeforeInitialization()

  2. init()

  3. BeanPostProcessor.postProcessAfterInitialization()

  4. destroy()

You may check this by writing simple example having sysout and check their sequence.

Solution 3 - Spring

Init and Destroy callback methods are part of Spring bean life cycle phases. The init method is going to be executed after bean instantiation. Similarly, The destroy method is going to be executed before bean finalization.

We can implement this functionality using implementing interfaces InitializingBean and DisposableBean, or using annotations @postconstruct and @predestroy, or declare the <bean> with init-method and destroy-method attributes.

BeanPostProcessor interface is used for extending the functionality of framework if want to do any configuration Pre- and Post- bean initialization done by spring container.

For Example: By default, Spring will not aware of the @PostConstruct and @PreDestroy annotation. To enable it, we have to either register CommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean configuration file. Here CommonAnnotationBeanPostProcessor is predefined BeanPostProcessor implementation for the annotations. Like:

@Required enables RequiredAnnotationBeanPostProcessor processing tool
@Autowired enables AutowiredAnnotationBeanPostProcessor processing tool

Solution 4 - Spring

And one more main diff is InitializingBean,DisposableBean related afterPropertiesSet() & destory() methods did not accept any paratmeters and return type also void, so we did not implement any custom logic. But coming to BeanPostProcess methods postProcessBeforeInitialization(Object bean,String beanName) and postProcessAfterInitilization(Object bean,String beanName) are accept those two paramaters and return type also Object so we are able to write initilzation logics as well as any custom login based on the passing bean...

These both callback method feautes are including the bean life cycle and the following are the life cycle as follows

  1. BeanPostProcessor.postProcessBeforeInitilazation()

  2. @postConstruct or InitializingBean.afterPropertiesSet() or initialization method which is
    defining in xml /*** here also it's following the same oredr if three ways are availiable **/

  3. BeanPostProcessor.postProcessAfterInitialization()

  4. @preDestroy or DisposibleBean.destroy() or destroy method which is defining in xml /*** here also it's following the same oredr if three ways are availiable **/

Solution 5 - Spring

Just a short supplement to all the answers above: If you have any generic logic, common logic that needs to be universally applied to all your Spring beans, such as the injection of a logger to your beans, setting of a properties file, setting default values to fields of your beans through reflection; you could put that logic into ONE single place: the @Overriden callbacks (eg: postProcessBeforeInitialization(Object arg0, String arg1) if you are implementing the BeanPostProcessor interface); instead of duplicating the same logic across all your beans.

Solution 6 - Spring

a)The postProcessBeforeInitialization() will be called before initialization of the bean.

b)Once the bean gets initialized, the different callbacks methods are called in the following order as per the Spring docs:

  1. Methods annotated with @PostConstruct
  2. afterPropertiesSet() as defined by the InitializingBean callback interface
  3. init method defined through the XML.

The main difference is that the above 3 methods get called after the initialization get completed by the postProcessBeforeInitialization() method.

Once these methods get completed the method postProcessAfterInitialization() will be called and then the destroy methods are called in the same order:

  1. Methods annotated with @PreDestroy

  2. destroy() as defined by the DisposableBean callback interface

  3. destroy() method defined through the XML.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuckyLukeView Question on Stackoverflow
Solution 1 - SpringEmil HView Answer on Stackoverflow
Solution 2 - SpringneoView Answer on Stackoverflow
Solution 3 - SpringPremrajView Answer on Stackoverflow
Solution 4 - SpringvjayView Answer on Stackoverflow
Solution 5 - SpringIqbalHamidView Answer on Stackoverflow
Solution 6 - SpringSandhya BhatView Answer on Stackoverflow