Spring容器扩展点:后置处理器BeanFactoryPostProcessor

BeanPostProcessor(Bean后置处理器)常用在对bean内部的值进行修改;实现Bean的动态代理等。 
BeanFactoryPostProcessor和BeanPostProcessor都是spring初始化bean时对外暴露的扩展点。但它们有什么区别呢? 
由《理解Bean生命周期》的图可知:BeanFactoryPostProcessor是生命周期中最早被调用的,远远早于BeanPostProcessor。它在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。也就是说,Spring允许BeanFactoryPostProcessor在容器创建bean之前读取bean配置元数据,并可进行修改。例如增加bean的属性和值,重新设置bean是否作为自动装配的侯选者,重设bean的依赖项等等。

在srping配置文件中可以同时配置多个BeanFactoryPostProcessor,并通过在xml中注册时设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。

BeanFactoryPostProcessor接口定义如下:

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

接口只有一个方法postProcessBeanFactory。该方法的参数是ConfigurableListableBeanFactory类型,实际开发中,我们常使用它的getBeanDefinition()方法获取某个bean的元数据定义:BeanDefinition。它有这些方法: 
这里写图片描述

看个例子: 
配置文件中定义了一个bean:

<bean id="messi" class="twm.spring.LifecycleTest.footballPlayer">
    <property name="name" value="Messi"></property>
    <property name="team" value="Barcelona"></property>
</bean>

创建类beanFactoryPostProcessorImpl,实现接口BeanFactoryPostProcessor:

public class beanFactoryPostProcessorImpl implements BeanFactoryPostProcessor{

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("beanFactoryPostProcessorImpl");
        BeanDefinition bdefine=beanFactory.getBeanDefinition("messi");
        System.out.println(bdefine.getPropertyValues().toString());
        MutablePropertyValues pv =  bdefine.getPropertyValues();  
            if (pv.contains("team")) {
                PropertyValue ppv= pv.getPropertyValue("name");
                TypedStringValue obj=(TypedStringValue)ppv.getValue();
                if(obj.getValue().equals("Messi")){
                    pv.addPropertyValue("team", "阿根延");  
                }
        }  
            bdefine.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    }
}

调用类:

public static void main(String[] args) throws Exception {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    footballPlayer obj = ctx.getBean("messi",footballPlayer.class);
    System.out.println(obj.getTeam());
}

输出:

PropertyValues: length=2; bean property ‘name’; bean property ‘team’ 
阿根延

在《PropertyPlaceholderConfigurer应用》提到的PropertyPlaceholderConfigurer这个类就是BeanFactoryPostProcessor接口的一个实现。它会在容器创建bean之前,将类定义中的占位符(诸如${jdbc.url})用properties文件对应的内容进行替换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值