Spring Bean Post Processor example

🌱 Understanding BeanPostProcessor in Spring Framework — with Example

In Spring, the BeanPostProcessor interface allows developers to hook into the bean lifecycle and perform custom actions before and after bean initialization.

It’s a powerful extension point that lets you modify bean instances or inject additional behavior after Spring has created and configured them — without changing the original bean code.


⚙️ What Is a BeanPostProcessor?

A BeanPostProcessor defines callback methods that are automatically invoked by the Spring container during bean creation.

It provides two key methods:

MethodDescription
postProcessBeforeInitialization(Object bean, String beanName)Called before the bean’s initialization callback (@PostConstruct, afterPropertiesSet(), etc.)
postProcessAfterInitialization(Object bean, String beanName)Called after the bean’s initialization is complete

With this, you can:

  • Inject custom logic before or after a bean is initialized.

  • Implement cross-cutting concerns like logging, metrics, auditing, or validation.

  • Wrap or modify bean instances dynamically.


🧩 Example — Custom BeanPostProcessor in Spring

In this example, we’ll:

  1. Define a simple Student bean.

  2. Create a MyBeanPostProcessor class.

  3. Configure both in Spring XML.

  4. Observe how the bean lifecycle is intercepted by our post-processor.


🧱 1. Spring XML Configuration (spring-core.xml)

<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-2.5.xsd"> <!-- Define the Student bean --> <bean id="studentBean" class="com.vinod.test.Student" scope="singleton" /> <!-- Register the custom BeanPostProcessor --> <bean class="com.vinod.test.MyBeanPostProcessor" /> </beans>

🧠 2. Implementing the BeanPostProcessor

package com.vinod.test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * Custom BeanPostProcessor to intercept bean initialization events. * * This class demonstrates how Spring allows developers to add * custom behavior before and after a bean is initialized. * * @author vinod */ public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Before Initialization : " + beanName); return bean; // you can return a proxy or modified bean here } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("After Initialization : " + beanName); return bean; } }

👩‍🎓 3. The Bean Class — Student.java

package com.vinod.test; public class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }

🚀 4. Test Class — SpringCoreScopeTest.java

package com.vinod.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Loads Spring context and retrieves a bean to demonstrate * BeanPostProcessor execution order. */ public class SpringCoreScopeTest { public static void main(String[] args) { // Load Spring context from XML configuration ApplicationContext context = new ClassPathXmlApplicationContext("spring-core.xml"); // Retrieve the Student bean Student student = (Student) context.getBean("studentBean"); student.setName("Vinod"); // Display the bean value System.out.println(student.getName()); } }

🧾 5. Output

Before Initialization : studentBean After Initialization : studentBean Vinod

🔍 How It Works — Step by Step

  1. The Spring container loads the XML configuration.

  2. It creates the studentBean instance.

  3. Before calling any initialization methods, Spring invokes
    postProcessBeforeInitialization() — printing "Before Initialization : studentBean".

  4. After the bean is initialized, Spring calls
    postProcessAfterInitialization() — printing "After Initialization : studentBean".

  5. The bean is then available for use in the application context.


🧠 When to Use BeanPostProcessor

You can use BeanPostProcessor to:

  • Inject custom logging or tracing.

  • Automatically wrap beans with proxies (e.g., AOP-style logic).

  • Perform validation or custom initialization.

  • Modify beans dynamically (for example, adding extra configuration).


🧱 Example Visualization

Spring Container │ ▼ [Bean Instantiation] │ ▼ → postProcessBeforeInitialization() │ ▼ [Bean Initialization] │ ▼ → postProcessAfterInitialization() │ ▼ [Bean Ready for Use]

⚡ Key Takeaways

ConceptDescription
InterfaceBeanPostProcessor (from org.springframework.beans.factory.config)
PurposeIntercept bean creation and apply custom logic
MethodspostProcessBeforeInitialization() and postProcessAfterInitialization()
Return TypeYou can return the same or a modified bean
ScopeApplies to all beans managed by the container

Spring Bean life cycle callback methods

 

There are two ways we can implement initialization/destruction call back methods in Spring Bean

1.Implementing Initialization/destruction interface

The org.springframework.beans.factory.InitializingBean interface specifies a single method
void afterPropertiesSet() throws Exception;

The org.springframework.beans.factory.DisposableBean interface specifies a single method
void destroy() throws Exception;

2. Xml based configuration

add init/destroy attribute in bean tag
init-method="init


In the below example, the call back methods are applied for Employee (XML Based) and Customer beans (Implements interfaces)

1. Create java beans


package com.vinod.test;

public class Employee {
    private String name;
    private String address;

    public String getName() {
        return name;
    }

//Getters and setters
    public void init() {
        System.out.println("Bean initializing");
    }

    public void destroy() {
        System.out.println("Bean destroying");
    }
}
 


package com.vinod.test;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Customer implements InitializingBean, DisposableBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Bean destroying");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Bean starting");
    }

}
 


2. Create spring configuration

<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-2.5.xsd">

   
    <bean id="employeeBean" class="com.vinod.test.Employee"
        init-method="init" destroy-method="destroy">
    </bean>
       
    <bean id="customer" class="com.vinod.test.Customer">
    </bean>
   
</beans>


3. Create a Test class


package com.vinod.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringInitializeTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-core-application-context.xml");
       
        //Employee bean
        Employee obj = (Employee) context.getBean("employeeBean");
        obj.setName("vinod-->Employee");
        System.out.println(obj.getName());
       
        //Customer bean
       
        Customer customer = (Customer) context.getBean("customer");
        customer.setName("vinod-->Customer");
        System.out.println(customer.getName());
    }

}
  

4. Output

Bean initializing

Bean starting

vinod-->Employee

vinod-->Customer 

Spring Bean scopes example

Spring Bean scopes

The Spring Framework supports following five scopes, three of which are available only if you use a web-aware ApplicationContext.

singleton
This scopes the bean definition to a single instance per Spring IoC container (default).

prototype
This scopes a single bean definition to have any number of object instances.

request
This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.

session
This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.

global-session
This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext

Example

Spring configuration

Note: By default scope is singleton ,not mandatory to specify this scope

<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-2.5.xsd">

    <bean id="studentBean" class="com.vinod.test.Student" scope="singleton">
    </bean>
</beans>


Test class 

package com.vinod.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringCoreScopeTest {

    public static void main(String arg[]) {
        // Getting beans from XML based bean configuration
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-core.xml");
        // Student bean
        Student obj = (Student) context.getBean("studentBean");
        obj.setName("vinod");
        System.out.println(obj.getName());
       
       
        Student obj1 = (Student) context.getBean("studentBean");   
        //Let us check whether getting the same object or not.
        System.out.println(obj1.getName());

    }
}
 

Output

vinod
vinod

Here we can see the same object we are getting it from the context during the second call as it is singleton.

Let us change the bean scope to prototype and run the above program.

    <bean id="studentBean" class="com.vinod.test.Student" scope=“prototype">

Output

vinod
null

…Done!!!

 

 

Spring Application Context implementations

Spring ApplicatonContext container

This container adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContextinterface.

The ApplicationContext includes all functionality of the BeanFactory, it is generally recommended over the BeanFactory. BeanFactory can still be used for light weight applications like mobile devices or applet based applications.

The most commonly used ApplicationContext implementations are:

FileSystemXmlApplicationContext: This container loads the definitions of the beans from an XML file. Here you need to provide the full path of the XML bean configuration file to the constructor.

ClassPathXmlApplicationContext This container loads the definitions of the beans from an XML file. Here you do not need to provide the full path of the XML file but you need to set CLASSPATH properly because this container will look bean configuration XML file in CLASSPATH.

WebXmlApplicationContext: This container loads the XML file with definitions of all beans from within a web application.

Example

// Getting beans from XML based bean configuration
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-core.xml");
        // Student bean
        Student obj = (Student) context.getBean("studentBean");
        obj.setName("vinod");
        System.out.println(obj.getName());

       
        ApplicationContext context1 = new FileSystemXmlApplicationContext("/Users/vinodkariyathungalkumaran/git/spring/spring-jmstemplate/src/main/resources/spring-core.xml");
        Student obj1 = (Student) context1.getBean("studentBean");
 

 

Spring BeanFactory example

 

Spring BeanFactory container

This is the simplest container providing basic support for Dependency Injection and defined by the Spring org.springframework.beans.factory.BeanFactory interface. The BeanFactory and related interfaces, such as BeanFactoryAware, InitializingBean, DisposableBean, are still present in Spring for the purposes of backward compatibility with the large number of third-party frameworks that integrate with Spring

1. XML Based configuration

<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-2.5.xsd">

    <bean id="studentBean" class="com.vinod.test.Student">
    </bean>
</beans>

2. Student.java

package com.vinod.test;

public class Student {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
 

3. Test class

package com.vinod.test;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BeanFactoryExample {

    public static void main(String[] args) {
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
                "spring-core.xml"));
        Student obj = (Student) factory.getBean("studentBean");
        System.out.println(obj.getClass().getName());
    }

}
 

4. Output

com.vinod.test.Student

What is new in JSF 2?

JSF 2 new features

Facelets

  1. Helps in designing the UI pages without using JSP
  2. facilitates templates

Composite Components

  1. Easy to define custom components only with XHTML and TLD definition

AJAX Support

  1. built-in AJAX support and can be added to any UI components by just added <f:ajax> tag

New Navigation rules

  1. Implicit Navigation (Navigation without navigation rules in faces-config.xml)
  2. Conditional Navigation (define pre-conditions for navigation rules in faces-config.xml using EL)
  3. Preemptive Navigation (More control over navigation rules using ConfigurableNavigationHandler API)

Annotations

  1. Can define Managed bean name and scope
  2. Component annotations like @FacesComponent, @FacesRenderer, etc., to design custom component
  3. Hibernate has release annotations that work with JSF for Bean Validation

 

Ref: http://en.wikipedia.org/wiki/JavaServer_Faces

Confusion Matrix + Precision/Recall (Super Simple, With Examples)

  Confusion Matrix + Precision/Recall (Super Simple, With Examples) 1) Binary Classification Setup Binary classification means the model p...

Featured Posts