Spring - BeanPostProcessor
Spring Framework provides BeanPostProcessor Interface. It allows custom modification of new bean instances that are created by the Spring Bean Factory. If we want to implement some custom logic such as checking for marker interfaces or wrapping beans with proxies after the Spring container finishes instantiating, configuring, and initializing a bean, we can plug in BeanPostProcessor implementations.
- It works with all beans in the container.
- It can replace bean instances.
- It is used internally by Spring for features like @Autowired and AOP.
Syntax:
org.springframework.beans.factory.config
public interface BeanPostProcessor
Methods in the BeanPostProcessor Interface
The BeanPostProcessor interface acts as a middleware in Spring's bean lifecycle, and it consists of two callback methods:
- postProcessBeforeInitialization() Method (Before bean initialization)
- postProcessAfterInitialization() Method (After bean initialization)
Method 1: postProcessBeforeInitialization()
To apply any custom logic to the given new bean instance before any bean initialization callbacks (like InitializingBean's afterPropertiesSet or a custom init-method), we can call this BeanPostProcessor method. The bean will already be populated with the property values, and the returned bean instance may be a wrapper around the original one.
Syntax:
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
Parameters:
- bean: The new bean instance.
- beanName: The name of the bean.
Return Type: Either the original or a wrapped bean instance to use. No subsequent BeanPostProcessors will be invoked, if null. And in case of errors, it throws BeansException.
When it Runs:
It runs after dependency injection, but before,
- @PostConstruct methods
- InitializingBean.afterPropertiesSet()
- Custom init-method
Method 2: postProcessAfterInitialization()
To apply any custom logic to the given new bean instance after any bean initialization callbacks (like InitializingBean's afterPropertiesSet or a custom init-method), we can call this BeanPostProcessor method.
The bean will already be populated with the property values and the returned bean instance may be a wrapper around the original one. This callback will be invoked for both the FactoryBean instance and the objects created by the FactoryBean. The post-processor can decide whether to apply to either the FactoryBean or created objects or both through the corresponding bean instance of the FactoryBean checks.
Syntax:
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
Parameters:
- bean: The new bean instance
- beanName: The name of the bean
Return Type: Either the original or a wrapped bean instance to use. No subsequent BeanPostProcessors will be invoked, if null. And in case of errors, it throws BeansException.
It runs after all initialization callbacks complete.
Registering and Ordering the BeanPostProcessors
We can plug in one or more BeanPostProcessor implementations to include custom logic, in this case, we can control these multiple BeanPostProcessor instances by setting the order property or by implementing the Ordered interface.
An ApplicationContext can autodetect BeanPostProcessor beans in its bean definitions and apply those to any beans that are subsequently created. In case of a plain BeanFactory, we need to register the post-processors programmatically applying them to all beans created through the bean factory.
BeanPostProcessor beans that are autodetected in an ApplicationContext will be ordered according to PriorityOrdered and Ordered interfaces. In contrast, BeanPostProcessor beans that are registered programmatically with a BeanFactory will be applied in the order of registration.
Complete Implementation Example
We will create a simple Spring application to get employee details using Eclipse IDE.
Step 1: Project Setup
- Create a new Java project 'Spring_Application' in Eclipse.
- Add Spring jar files to the project. We can download the latest jar files from Maven Repository.
- Now, we need to create the required Java classes and the configuration files under the project.
Include the Spring Core dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.9</version>
</dependency>
Below will be the final project structure of the application.

Step 2: Create a Custom Processor
Create a CustomProcessor.java file that implements the BeanPostProcessor interface and implements the two callback methods in it.
CustomProcessor.java:
// Java Program to Illustrate CustomProcessor Class
package com.geeks.beans;
// Importing required classes
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
// Class
// Implementing BeanPostProcessor interface
public class CustomProcessor implements BeanPostProcessor {
// Method 1
public Object postProcessBeforeInitialization(
Object bean, String beanName) throws BeansException
{
System.out.println(
"postProcessBeforeInitialization() is called for EmployeeImpl");
return bean;
}
// Method 2
public Object postProcessAfterInitialization(
Object bean, String beanName) throws BeansException
{
System.out.println(
"postProcessAfterInitialization() is called for EmployeeImpl");
return bean;
}
}
Step 3: Create an Employee.java File
To define variables and their getter/setter methods.
Employee.java:
// Java Program to Illustrate Employee Class
package com.geeks.beans;
// Class
public class Employee {
// Class data members
private String name;
private String mail;
// Getter
public String getName() { return name; }
// Setter
public void setName(String name) { this.name = name; }
// Getter
public String getMail() { return mail; }
// Setter
public void setMail(String mail) { this.mail = mail; }
}
Step 4: Create an EmployeeImpl.java File
To create a new Employee object. Define Init and Destroy methods of the class.
EmployeeImpl.java:
// Java Program Implementing Employee Class
package com.geeks.beans;
// Class
public class EmployeeImpl {
// Method 1
public Employee createEmp()
{
// Creating Employee class object
// inside EmployeeImpl class
Employee e = new Employee();
// Custom setters
e.setName("Geek");
e.setMail("test@email.com");
return e;
}
// Method 2
public void initBean()
{
System.out.println("EmployeeImpl is Initialized.");
}
// Method 3
public void destroyBean()
{
System.out.println("EmployeeImpl is Destroyed.");
}
}
Step 5: Create applicationContext.xml
Create Spring configuration file to include bean definitions. Register the BeanPostProcessor in the configuration file.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanPostProcessor" class="com.geeks.beans.CustomProcessor" />
<bean id="impl" class="com.geeks.beans.EmployeeImpl" init-method="initBean" destroy-method="destroyBean"/>
</beans>
Step 6: Create an EmployeeTest.java File
To get the bean and run the application.
EmployeeTest.java:
// Java Program to Illustrate EmployeeTest Class
package com.geeks.beans;
// Importing required classes
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
// Class
public class EmployeeTest {
// Main driver method
public static void main(String[] args)
{
// Creating object of ApplicationContext,
// EmployeeImpl, and Employee class inside main()
// method
ApplicationContext con
= new ClassPathXmlApplicationContext(
"com/geeks/resources/applicationContext.xml");
EmployeeImpl impl
= (EmployeeImpl)con.getBean("impl");
Employee emp = impl.createEmp();
System.out.println("Employee Details");
System.out.println("Name: " + emp.getName()
+ ", Email address: "
+ emp.getMail());
((ClassPathXmlApplicationContext)con).close();
}
}
Step 7: Run the Application
Run the application as a Java application. We will get the below output in the console.

As we can see in the output, postProcessBeforeInitialization() is called before the initialization of the bean and once it is done, postProcessAfterInitialization() method is called and then the rest of the process completed. So, we can include any custom logic using post-processors to the new bean instances either before or after the bean initializations.