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.
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); }
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.
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>
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("spring.xml")); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setLocation(new FileSystemResource("databaseConfig.properties")); cfg.postProcessBeanFactory(factory);
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
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; } }
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 belowshape.propertiespointC.x=20 pointC.y=0Now 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.javapackage 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 prepareRefreshINFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ab50cd: startup date [Thu Jul 05 00:43:27 IST 2012]; root of context hierarchyJul 5, 2012 12:43:27 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitionsINFO: Loading XML bean definitions from class path resource [spring.xml]Jul 5, 2012 12:43:27 AM org.springframework.core.io.support.PropertiesLoaderSupport loadPropertiesINFO: 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 preInstantiateSingletonsINFO: 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)
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…