Open In App

Spring - BeanPostProcessor

Last Updated : 15 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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:

  1. postProcessBeforeInitialization() Method (Before bean initialization)
  2. 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.

Project Structure


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
// 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
// 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
// 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("[email protected]");
        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
<?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
// 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.

Output

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.


Next Article
Article Tags :
Practice Tags :

Similar Reads