Spring Core

BeanFactoryPostProcessor in Spring

In this article, we will explore BeanFactoryPostProcessor in Spring. BeanFactoryPostProcessor works on the bean definitions or configuration meta data of the bean before beans are actually created. Spring provides multiple BeanFactoryPostProcessor beans, so it invoked to resolve run time dependencies such reading value from external property files. In Spring application, BeanFactoryPostProcessor can modify the definition of any bean.

BeanFactoryPostProcessor in Spring

If you define a BeanFactoryPostProcessor in one container, it will only be applied to the bean definitions in that container.

public interface BeanFactoryPostProcessor {
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
}

Customizing beans with BeanPostProcessors

In previous chapter we have been seen that how to Customizing beans with BeanPostProcessors:
A   bean   post-processor   is   a    java   class   which   implements    the org.springframework.beans.factory.config.BeanPostProcessor interface, which consists of two callback methods
(postProcessAfterInitialization(Object bean, String beanName) & postProcessBeforeInitialization(Object bean, String beanName)).

When such a class is registered as a post-processor with the BeanFactory, for each bean instance that is created by the BeanFactory, the post-processor will get a callback from the BeanFactory before any initialization methods (afterPropertiesSet and any declared init method) are called, and also afterwords.

 

Customizing bean factories with BeanFactoryPostProcessors

A   bean   factory    post-processor    is    a    java   class    which   implements   the org.springframework.beans.factory.config.BeanFactoryPostProcessor interface. It is executed manually (in the case of the BeanFactory) or automatically (in the case of the ApplicationContext) to apply changes of some sort to an entire BeanFactory, after it has been constructed.
 Spring includes a number of pre-existing bean factory post-processors, such as given below

PropertyResourceConfigurer and PropertyPlaceHolderConfigurer – implemented as a bean factory post-processor, is used to externalize some property values from a BeanFactory definition, into another separate file in Java Properties format. This is useful to allow to developer to declare some key property as properties file. As given below example show the database connection related information in the following property file.

databaseConfig.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://davproductionDB:3306
jdbc.username=root
jdbc.password=root

Now in the bean configuration file has the dataSource bean as below.

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
  <property name="driverClassName" value="${jdbc.driverClassName}">
  <property name="url" value="${jdbc.url}">
  <property name="username" value="${jdbc.username}">
  <property name="password" value="${jdbc.password}">
</property></property></property></property></bean>

To use this with a BeanFactory, the bean factory post-processor is manually executed on it:

XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("spring.xml"));
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("databaseConfig.properties"));
cfg.postProcessBeanFactory(factory);

To use this with a ApplicationContext, the bean factory post-processor is automatically executed on it:

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Now see the full running application which using BeanFactoryPostProcessor interceptor to config the BeanFactory at time of initialization.

Triangle.java

package com.dineshonjava.sdnext.beanFactoryPP.tutorial;

public class Triangle
{
 private Point pointA;
 private Point pointB;
 private Point pointC;
 /**
  * @param pointA the pointA to set
  */
 public void setPointA(Point pointA) {
  this.pointA = pointA;
 }

 /**
  * @param pointB the pointB to set
  */
 public void setPointB(Point pointB) {
  this.pointB = pointB;
 }

 /**
  * @param pointC the pointC to set
  */
 public void setPointC(Point pointC) {
  this.pointC = pointC;
 }

 public void draw()
 {
System.out.println("PointA is ("+pointA.getX()+", "+pointA.getY()+")");
System.out.println("PointB is ("+pointB.getX()+", "+pointB.getY()+")");
System.out.println("PointC is ("+pointC.getX()+", "+pointC.getY()+")");
 }
}


Point.java

package com.dineshonjava.sdnext.beanFactoryPP.tutorial;

public class Point
{
 private int x;
 private int y;
 /**
  * @return the x
  */
 public int getX() {
  return x;
 }
 /**
  * @param x the x to set
  */
 public void setX(int x) {
  this.x = x;
 }
 /**
  * @return the y
  */
 public int getY() {
  return y;
 }
 /**
  * @param y the y to set
  */
 public void setY(int y) {
  this.y = y;
 }
}
Now define the bean configuration file.

spring.xml

<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:>
In the above configuration file, bean id "pointC" have the two properties x and y the value of these two properties read from the property file (shape.properties)as given below
shape.properties
pointC.x=20
pointC.y=0
Now define a class which implement the BeanFactoryPostProcessor interface for the config the bean factory at the time of initialization with given property file value.


BeanFactoryPPDemo.java

package com.dineshonjava.sdnext.beanFactoryPP.tutorial;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.FileSystemResource;

public class BeanFactoryPPDemo implements BeanFactoryPostProcessor  
{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
 {
 PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();  
 cfg.setLocation(new FileSystemResource("shape.properties"));  
 cfg.postProcessBeanFactory(beanFactory); 
 System.out.println("Bean factory post processor is initialized");
 }
}
If every thing is Ok then run the following main application file and see the console.

DrawingApp.java

package com.dineshonjava.sdnext.beanFactoryPP.tutorial;

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

/**
 * @author Dinesh Rajput
 *
 */
public class DrawingApp 
{
 /**
  * @param args
  */
 public static void main(String[] args) 
 {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Triangle triangle = (Triangle) context.getBean("triangle");
triangle.draw();
 }

}
Output:
Jul 5, 2012 12:43:27 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ab50cd: startup date [Thu Jul 05 00:43:27 IST 2012]; root of context hierarchy
Jul 5, 2012 12:43:27 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Jul 5, 2012 12:43:27 AM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from file [F:my workspacespring16BeanFactoryPPDemoshape.properties]

Bean factory post processor is initialized

Jul 5, 2012 12:43:27 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons

INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@14c1103: defining beans [triangle,pointA,pointB,pointC,com.dineshonjava.sdnext.beanFactoryPP.tutorial.BeanFactoryPPDemo#0]; root of factory hierarchy
PointA is (0, 0)
PointB is (-20, 0)
PointC is (20, 0)

See the project structure for that application.

 

Spring Related Topics you may like

 

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago