Spring in Spring BeanFactoryPostProcessor and BeanPostProcessor are extension points exposed outside of the initialization bean. Two interfaces look similar from the name, but the role and usage scenarios are different.
Spring IoC container bean definition allows BeanFactoryPostProcessor read before instantiating any bean container (metadata configuration), and it can be modified. And can define multiple BeanFactoryPostProcessor, the execution order is determined by setting individual BeanFactoryPostProcessor 'order' attribute.
Register BeanFactoryPostProcessor instance a need to define a Java class implemented BeanFactoryPostProcessor interface and override method postProcessorBeanFactory interface. Definition information may be acquired through the bean beanFactory, and can be modified definition information bean. This is the biggest difference and BeanPostProcessor
public interfac BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
spring.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.xsd"> <!-- 支持Spring注解 --> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> <!-- 注册一个BeanPostProcessor --> <bean id="postProcessor" class="com.test.spring.PostProcessor"/> <!-- 注册一个BeanFactoryPostProcessor --> <bean id="factoryPostProcessor" class="com.test.spring.FactoryPostProcessor"/> <!-- 普通bean --> <bean id="beanFactoryPostProcessorTest" class="com.test.spring.BeanFactoryPostProcessorTest"> <property name="name" value="张三"/> <property name="sex" value="男"/> </bean> </beans>
BeanPostProcessor.java
package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * bean后置处理器 * @author zss * */ public class PostProcessor implements BeanPostProcessor{ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置处理器处理bean=【"+beanName+"】开始"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("后置处理器处理bean=【"+beanName+"】完毕!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return bean; } }
BeanFactoryPostProcessor.java
package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class FactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory( ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("******调用了BeanFactoryPostProcessor"); String[] beanStr = configurableListableBeanFactory .getBeanDefinitionNames(); for (String beanName : beanStr) { if ("beanFactoryPostProcessorTest".equals(beanName)) { BeanDefinition beanDefinition = configurableListableBeanFactory .getBeanDefinition(beanName); MutablePropertyValues m =beanDefinition.getPropertyValues (); IF (m.contains ( "name" )) { m.addPropertyValue ( "name", "Zhao Si" ); System.out.println ( "", "" modify the initial value of the name attribute " ); } } } } }
BeanFactoryPostProcessorTest.java
package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class BeanFactoryPostProcessorTest implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public void setBeanFactory(BeanFactory paramBeanFactory) throws BeansException { System.out.println("》》》调用了BeanFactoryAware的setBeanFactory方法了"); } @Override public void setBeanName (String o paramString) { System.out.println ( "" "" calls setBeanName BeanNameAware of the method " ); } @Override public void the destroy () throws Exception { System.out.println ( " "" "calls the destroy method of DisposableBean" ); } @Override public void afterPropertiesSet () throws Exception { System.out.println ( "", "" call the afterPropertiesSet Initailization the method " ); } @Override public String toString () { return "BeanFactoryPostProcessorTest [name=" + name + ", sex=" + sex + "]"; } }
Test case:
package com.test.spring; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class T { ApplicationContext applicationcontext=null; @Before public void before() { System.out.println("》》》Spring ApplicationContext容器开始初始化了......"); applicationcontext= new ClassPathXmlApplicationContext(new String[]{"spring-service.xml"}); System.out.println("》》》Spring ApplicationContext容器初始化完毕了......"); } @Test public void test() { //BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class); BeanFactoryPostProcessorTest beanFactoryPostProcessorTest=applicationcontext.getBean(BeanFactoryPostProcessorTest.class); System.out.println(beanFactoryPostProcessorTest.toString()); } }
Test Results:
"" "Spring ApplicationContext the container starts initialization ...... 2017-03-20 14:36:10 the INFO: Refreshing the ClassPathXmlApplicationContext-org.springframework.context.support.ClassPathXmlApplicationContext@17ad352e: Startup DATE [Mon 20 is 14-Mar: CST 2017 36:10]; root of context Hierarchy 2017-03-20 14:36:10 INFO: XmlBeanDefinitionReader-Loading XML bean from class path Resource Definitions [Spring - service.xml] ****** called BeanFactoryPostProcessor " "" modify the initial value of the name attribute "" "calls setBeanName BeanNameAware of the method " "" BeanFactoryAware called setBeanFactory method of the post-processor the bean = [start] beanFactoryPostProcessorTest postprocessor start calling the "" " the method of afterPropertiesSet Initailization called the post-processor bean= [] BeanFactoryPostProcessorTest finished! Postprocessor call ended "" "Spring ApplicationContext container initialization finished ...... BeanFactoryPostProcessorTest [name = Zhao Si, sex = male]
As can be seen from the test results beanFactoryPostProcessorTest name value defined by "John Doe" to "Zhao Si", also found in the first order of execution method postProcessorBeanFactory BeanPostProcessor interface methods.
It built a number of BeanFactoryPostProcessor implementation class in Spring:
- org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
- org.springframework.beans.factory.config.PropertyOverrideConfigurer
- org.springframework.beans.factory.config.CustomEditorConfigurer: Property Editor is used to register a custom