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:
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.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:
BeanPostProcessor.postProcessBeforeInitialization()
init()
BeanPostProcessor.postProcessAfterInitialization()
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
Thanks for reading.