Spring Bean Post Processor

    0 Votes


Till now, what we have learned in spring is all configuration and how to implement those in Spring configuration file. Based on the configuration file, Spring container manage the bean lifecycle of the bean. But if the developer want to intercept that process, what should be done? This article will help you learn all about bean post processors.

Many times, we may need to hook up with bean lifecycle and need to perform certain task on bean by programming. Post processor are the answers to it and with the help of post processor, we can hook up with bean life cycle. There is two kind of Processors.
  • BeanPostProcessor
  • BeanFactoryPostProcessor

 

BeanPostProcessor
BeanPostprocessor are intercepts, after all the beans are loaded but just before the initialization and just after the initialization of every bean. To be precise, after Spring beans are loaded in container, BeanPostprocessor’s postProcessBeforeIntialization() has been called. Then, after the call of custom init() method, postProcessAfterIntialization() method will be called. So developer can perform custom tasks in this methods.
To create a BeanPostProcessor, developer has to create a POJO class which will implements BeanPostProcessor interface, and then need to register itself in Spring Configuration file. Let’s take an example.
Suppose we want to replace any ‘s’ with ‘t’, we create a BeanPostProcessor which will examine every property of bean and then replace any ‘s’ or ‘S’ with ‘t’ or ‘T’.

 

BeanPostProcessor.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-3.0.xsd">

   <bean id="postprocessor" class="com.example.postprocessor.ReplaceProcessor"/>
   
   <bean id="text" class="com.example.postprocessor.TextEditor">
    <property name="text" value="Hello friends! Welcome to Spring"/>
   </bean>
</beans>


Java Code

package com.example.postprocessor;

import java.lang.reflect.Field;

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

public class ReplaceProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		// TODO Auto-generated method stub
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		  Field[] field = bean.getClass().getDeclaredFields();
		  String val=null;
		  for(Field f : field)
		  {
			  if(String.class.equals(f.getType()))
			  {
				  f.setAccessible(true);
				 
				try {
					val = (String)f.get(bean);
					val = val.replaceAll("s", "t");
					val = val.replaceAll("S", "T");
					f.set(bean, val);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
		  }
		  return bean;
	}
}


package com.example.postprocessor;

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

import com.example.hello.HelloWorld;

public class TextEditor {
	
	private String text;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	@Override
	public String toString() {
		return "TextEditor [text=" + text + "]";
	}
	
	public static void main(String[] args) 
	{
	    ApplicationContext ctx = new ClassPathXmlApplicationContext("configFiles/BeanPostProcessor.xml");
	   	
	    TextEditor text = (TextEditor) ctx.getBean("text");
	    System.out.println(text.getText());
	}
}

Output :

Hello friendt! Welcome to Tpring


Check the code of ReplaceProcessor. In postProcessAfterIntialization method, first we extract the fields (java properties) using reflection then check if the field is String type or not. If it is String get the value and replace any s with t.

The output has been change from

Hello friends! Welcome to Spring to Hello friendt! Welcome to Tpring.

BeanFactoryPostProcessor

BeanFactoryPostProcessor is the intercept after all beans are loaded. In Standard J2EE application, often we need to read value from a property file. So, now the question is should it be possible in Spring. The Answer is absolutely possible by BeanFactoryPostProcessor , after all beans are loaded BeanFactoryPostProcessor, replace the placeholder with actual value.

Spring offers a PropertyPlaceHolderConfigurer which is a kind of a BeanFactoryPostProcessor . By using that, we can replace placeholder with actual value.

Apart from that BeanNameAware and BeanFactoryAware ApplicationContextAware are example of BeanFactoryPostProcessor. Let see the example, How to load a property file using PropertyPlaceHolderConfigurer. 


BeanFactoryPostProcessor.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-3.0.xsd">

   <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location">
		<value>configFiles/text.properties</value>
	</property>
</bean>
   
   <bean id="text" class="com.example.postprocessor.TextEditor">
    <property name="text" value="${text}"/>
   </bean>

</beans>


text.properties under configFiles

text = text is loaded from property file.

package com.example.postprocessor;

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

import com.example.hello.HelloWorld;

public class TextEditor {
	
	private String text;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	@Override
	public String toString() {
		return "TextEditor [text=" + text + "]";
	}
	
	public static void main(String[] args) {
	    ApplicationContext ctx = new ClassPathXmlApplicationContext("configFiles/BeanFactoryPostProcessor.xml");
	   	
	        TextEditor text =(TextEditor) ctx.getBean("text");
	        System.out.println(text.getText());
	}
}


Output :

text is loaded from property file.

Look at BeanFactoryPostProcessor.xml here. We create a entry of propertyPlaceHolderCinfigurer and set the name and location of properties file.

In TextEditor bean, we create a SPEL (Spring expression language) ${text}, that is the key of properties file. Value would be replaced in runtime.

spring bean post processor

PropertyPlaceHolderConfigurer’s Action on Spring Bean.

Related Articles

Spring Framework - Overview
Spring Architecture
Step by step guide for Spring configuration
Building First Spring application
Spring Bean XML File
Spring Container
Spring Bean - Learn with an Example
Spring Bean Scope
Spring Bean Life Cycle
Spring Inner Bean
Spring Autowiring
Spring Autowiring Types
Spring Qualifier with Autowiring
Spring Collection Injection
Spring Inheritance
Spring Event Handling
Dependency Injection
Spring AOP
Spring AOP Example

Popular Videos

How to Overcome Shyness in Communication

How to Overcome Shyness in Communication using 4 Simple Steps.

Got a tip or Question?
Let us know