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
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>
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");
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:security="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans"> <bean autowire="byName" class="com.dineshonjava.sdnext.beanFactoryPP.tutorial.Triangle" id="triangle"></bean> <bean class="com.dineshonjava.sdnext.beanFactoryPP.tutorial.Point" id="pointA"> <property name="x" value="0"></property> <property name="y" value="0"></property> </bean> <bean class="com.dineshonjava.sdnext.beanFactoryPP.tutorial.Point" id="pointB"> <property name="x" value="-20"></property> <property name="y" value="0"></property> </bean> <bean class="com.dineshonjava.sdnext.beanFactoryPP.tutorial.Point" id="pointC"> <property name="x" value="${pointC.x}"></property> <property name="y" value="${pointC.y}"></property> </bean> <bean class="com.dineshonjava.sdnext.beanFactoryPP.tutorial.BeanFactoryPPDemo"></bean> </beans>
shape.properties
pointC.x=20 pointC.y=0
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"); } }
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(); } }
Bean factory post processor is initialized
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)
- Spring Interview Questions and Answers
- Spring AOP Interview Questions and Answers
- Spring MVC Interview Questions
- Spring Security Interview Questions and Answers
- Spring REST Interview Questions and Answers
- Spring Boot Interview Questions and Answers
- Spring Boot Microservices Interview Questions and Answers
- Dependency Injection (DI) in Spring
- Spring IoC Container
- What is Bean Factory in Spring
- ApplicationContext in Spring
- Bean Autowiring in Spring
- Spring Bean Scopes
- Create Custom Bean Scope in Spring Example
- Using ApplicationContextAware in Spring
- Spring Bean Life Cycle and Callbacks
- BeanPostProcessor in Spring
- Annotations in Spring and Based Configuration
- Spring JSR-250 Annotations
- JSR 330 Annotations in Spring
- Spring @Component, @Repository, @Service and @Controller Stereotype Annotations
- Method injection with Spring using Lookup method property
- Spring AOP-Introduction to Aspect Oriented Programming
- @Aspect Annotation in Spring
- Spring AOP AspectJ @Before Annotation Advice Example
- Spring AOP Before Advice Example using XML Config
- Spring AOP AspectJ @After Annotation Advice Example
- Spring AOP After Advice Example using XML Config
- Spring AOP AspectJ @AfterReturning Annotation Advice Example
- Spring AOP After-Returning Advice Example using XML Config
- Spring AOP AspectJ @AfterThrowing Annotation Advice Example
- Spring AOP After Throwing Advice Example using XML Config
- Spring AOP AspectJ @Around Annotation Advice Example
- Spring AOP Around Advice Example using XML Config
- Spring AOP Proxies in Spring
- Spring AOP Transaction Management in Hibernate
- Spring Transaction Management
- Spring Declarative Transaction Management Example
- Spring AOP-Ordering of Aspects with Example
- Spring Security Java Based Configuration with Example
- Spring Security XML Namespace Configuration Example