博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring点滴十一:Spring中BeanFactoryPostProcessor和BeanPostProcessor区别
阅读量:6370 次
发布时间:2019-06-23

本文共 7478 字,大约阅读时间需要 24 分钟。

     Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点。两个接口从名字看起来很相似,但是作用及使用场景却不同。

关于BeanPostProcessor介绍在这篇文章中已经讲过:这里主要介绍BeanFactoryPostProcessor。

    Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置'order'属性来确定各个BeanFactoryPostProcessor执行顺序。

   注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别

public interface BeanFactoryPostProcessor {                /**          * Modify the application context's internal bean factory after its standard          * initialization. All bean definitions will have been loaded, but no beans          * will have been instantiated yet. This allows for overriding or adding          * properties even to eager-initializing beans.          * @param beanFactory the bean factory used by the application context          * @throws org.springframework.beans.BeansException in case of errors          */          void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;            }

spring.xml

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", "赵四");                     System.out.println("》》》修改了name属性初始值了");                }            }        }    }}
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 paramString) {        System.out.println("》》》调用了BeanNameAware的setBeanName方法了");    }    @Override    public void destroy() throws Exception {        System.out.println("》》》调用了DisposableBean的destroy方法了");            }    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("》》》调用了Initailization的afterPropertiesSet方法了");    }    @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());    }}

测试结果:

》》》Spring ApplicationContext容器开始初始化了......

2017-03-20 14:36:10  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@17ad352e: startup date [Mon Mar 20 14:36:10 CST 2017]; root of context hierarchy
2017-03-20 14:36:10  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [spring-service.xml]
******调用了BeanFactoryPostProcessor
》》》修改了name属性初始值了
》》》调用了BeanNameAware的setBeanName方法了
》》》调用了BeanFactoryAware的setBeanFactory方法了
后置处理器处理bean=【beanFactoryPostProcessorTest】开始
后置处理器开始调用了
》》》调用了Initailization的afterPropertiesSet方法了
后置处理器处理bean=【beanFactoryPostProcessorTest】完毕!
后置处理器调用结束了
》》》Spring ApplicationContext容器初始化完毕了......
BeanFactoryPostProcessorTest [name=赵四, sex=男]
---------------------------------------------------------------------------------------------------------
从测试结果中可以看到beanFactoryPostProcessorTest定义的name值由"张三"变为"赵四",同时发现postProcessorBeanFactory方法执行顺序先于BeanPostProcessor接口中方法。

***************************************************************************************************************************

   在Spring中内置了一些BeanFactoryPostProcessor实现类:

  • org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
  • org.springframework.beans.factory.config.PropertyOverrideConfigurer
  • org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器

     

    

    备注:下一篇将会介绍PropertyPlaceHoldConfigurer在Spring机制中如何读取配置文件的信息

 

转载于:https://www.cnblogs.com/sishang/p/6588542.html

你可能感兴趣的文章
服务器架构
查看>>
【Android学习】Android studio 使用AIDL
查看>>
【20160924】GOCVHelper MFC增强算法(2)
查看>>
阿里云安全肖力:云的六大安全基因助力企业构建智能化安全体系
查看>>
豆瓣阅读报告生成器
查看>>
building with Gulp
查看>>
首个不怕被盗取生物特征的生物识别技术问世
查看>>
Java虚拟机管理的内存运行时数据区域解释
查看>>
OpenPOWER全产业链协同打通大数据Hadoop的再创新轨道
查看>>
阿里巴巴并购安全公司翰海源
查看>>
连云存储魔力象限都进不了,就别提三年之内中国第一了吧!
查看>>
为什么“私有云”计算值得考虑
查看>>
《OpenACC并行程序设计:性能优化实践指南》一 2.3 描述数据移动
查看>>
《数据虚拟化:商务智能系统的数据架构与管理》一 1.7 数据虚拟化的技术优势...
查看>>
新华三新IT 以开放之力助新农信发展
查看>>
企业高效研发实践专场,加速研发效能体系升级
查看>>
为啥神经网络里的BP算法花了那么久才被发明?
查看>>
iOS编程中throttle的那些事
查看>>
智能数据连接世界
查看>>
BMC报告:数字化业务驱动对大型机的需求
查看>>