Quantcast
Channel: Tech Tutorials
Viewing all articles
Browse latest Browse all 938

BeanPostProcessor in Spring Framework

$
0
0

The BeanPostProcessor interface in the Spring framework defines callback methods that you can implement to perform some logic on the bean instances.

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.

Note that BeanPostProcessors operate on bean instances; the Spring IoC container instantiates a bean instance and then BeanPostProcessors do their work on those created instances. These instances are passed as argument to the callbeack methods.

BeanPostProcessor callback methods

The org.springframework.beans.factory.config.BeanPostProcessor interface has the following two callback methods.

  • Object postProcessBeforeInitialization(Object bean, String beanName)- This callback method is called before container initialization methods (such as InitializingBean’s afterPropertiesSet() and any declared init method) are called
  • Object postProcessAfterInitialization(Object bean, String beanName) - This method is called after any bean initialization callbacks.

Configuring more than one BeanPostProcessor

You can configure multiple BeanPostProcessor instances. You can also control the order in which these BeanPostProcessors execute by setting the order property. For that the BeanPostProcessor implemenation class must implement the Ordered interface too.

BeanPostProcessor is called on all the beans

BeanPostProcessor callback methods are called on each bean created by the Springcontainer.

Usage of BeanPostProcessor

A bean post-processor typically checks for callback interfaces or may wrap a bean with a proxy.

BeanPostProcessor Example

A typical use case for BeanPostProcessor is if you want to have some callback methods for specific type of bean.

Let’s say you have an interface IPayment and two implementation classes CashPayment and CardPayment. For these two beans only (out of all the configured beans) you want some logic to be performed (like doing some validation, checking some value) then you can create a BeanPostProcessor and in it’s callback method postProcessAfterInitialization you can use instanceOf operator to verify if bean is of specific type and then call the method you want.

Inerface IPayment


public interface IPayment extends PaymentCallBack {
void executePayment();
}

Interface PaymentCallBack


public interface PaymentCallBack {
void processInstance(IPayment bean);
}

CashPayment.java


public class CashPayment implements IPayment{
public void executePayment() {
System.out.println("Perform Cash Payment ");
}
@PostConstruct
public void annoInitMethod(){
System.out.println("Calling InitMethod for CashPayment");
}
@Override
public void processInstance(IPayment bean) {
System.out.println("processInstance method called with bean " + bean);

}
}

CardPayment.java


public class CardPayment implements IPayment{
public void executePayment() {
System.out.println("Perform Card Payment ");
}
@PostConstruct
public void annoInitMethod(){
System.out.println("Calling InitMethod for CardPayment");
}
@Override
public void processInstance(IPayment bean) {
System.out.println("processInstance method called with bean " + bean);
}
}

In these classes you can see that Spring bean life cycle initialization method annotated with @PostConstruct is used to see when bean is actually initialized.

BeanPostProcessor Class


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

public class InstantiationBeanPostProcessor implements BeanPostProcessor, Ordered {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("In postProcessBeforeInitialization method");
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {

System.out.println("In postProcessAfterInitialization method");
if(bean instanceof IPayment){
((IPayment) bean).processInstance((IPayment)bean);
}
return bean;
}

@Override
public int getOrder() {
// TODO Auto-generated method stub
return 0;
}

}

XML Configuration


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />

<bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
<bean id="cardPaymentBean" class="org.netjs.exp.Spring_Example.CardPayment" />

<bean class="org.netjs.exp.Spring_Example.InstantiationBeanPostProcessor"/>

</beans>

Notice how the InstantiationBeanPostProcessor is simply defined. It does not even have a name, and because it is a bean it can be dependency-injected just like any other bean.

You can use the following code to run the preceding code and configuration.

public class App {
public static void main( String[] args ){

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
("appcontext.xml");
//System.out.println("Loading AnnotationConfig app context");
IPayment cashBean = (IPayment) context.getBean("cashPaymentBean");
IPayment cardBean = (IPayment) context.getBean("cardPaymentBean");
context.close();
}
}

Output


In postProcessBeforeInitialization method
Calling InitMethod for CashPayment
In postProcessAfterInitialization method
processInstance method called with bean org.netjs.exp.Spring_Example.CashPayment@1e397ed7
In postProcessBeforeInitialization method
Calling InitMethod for CardPayment
In postProcessAfterInitialization method
processInstance method called with bean org.netjs.exp.Spring_Example.CardPayment@490ab905

That's all for this topic BeanPostProcessor in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Different Bean Scopes in Spring
  2. Bean Definition Inheritance in Spring
  3. How to Inject Prototype Scoped Bean in Singleton Bean
  4. Lazy Initializing Spring Beans
  5. Injecting Inner Bean in Spring

You may also like -

>>>Go to Spring Tutorial Page


Viewing all articles
Browse latest Browse all 938

Trending Articles