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

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

BeanPostProcessor is interface that tells spring to do some action while initializing the bean. BeanPostProcessor can be used to do custom instantiation logic for several beans.

For example, 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 a single place, instead of duplicating the same logic across all your beans.

BeanPostProcessor interface has two methods:

  1. postProcessBeforeInitialization() – 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.

Methods executed in the following sequence in the life cycle:

  1. BeanPostProcessor.postProcessBeforeInitialization()
  2. init()
  3. BeanPostProcessor.postProcessAfterInitialization()
  4. destroy()

From the Spring doc you will find something similar to the following:

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.

Let’s move on to an example how BeanPostProcessor works in Spring framework.

POJO Class

package com.roytuts.spring.beanpostprocessor.example;

public class Employee {

	private int id;
	private String name;

	public Employee(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + "]";
	}

}

BeanPostProcessor

We implement BeanPostProcessor interface as given below to check how it works. The method postProcessBeforeInitialization() gets called before bean initialization and postProcessAfterInitialization() gets called after bean initialization.

package com.roytuts.spring.beanpostprocessor.example;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class EmployeeBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("Called after initilizing bean -> " + beanName);
		return bean;
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("Called before initializing bean -> " + beanName);
		return bean;
	}

}

Config Class

Configuration class is required to define beans.

package com.roytuts.spring.beanpostprocessor.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

	@Bean
	public EmployeeBeanPostProcessor employeeBeanPostProcessor() {
		return new EmployeeBeanPostProcessor();
	}

	@Bean
	public Employee employee() {
		return new Employee(12345, "Asish");
	}

}

Testing BeanPostProcessor

Now we will retrieve the bean from ApplicationContext as follows:

package com.roytuts.spring.beanpostprocessor.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class BeanPostProcessorApp {

	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

		Employee e = context.getBean(Employee.class);

		System.out.println(e);

		((ConfigurableApplicationContext) context).close();
	}

}

Executing the above class will give you the following output:

Called before initializing bean -> employee
Called after initilizing bean -> employee
Employee [id=12345, name=Asish]

Source Code

Download

Thanks for reading.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *