Spring应用手册-BeanFactoryPostProcessor接口

戴着假发的程序员出品 抖音ID:戴着假发的程序员欢迎关注

BeanFactoryPostProcessor接口

spring应用手册(第五部分)


BeanFactoryPostProcessor是bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。

先看看源码:

package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
/**
 * Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {
   /**
    * 处理方法(钩子方法)
    * @param beanFactory 当前的工厂对象,我们可以通过这个工厂对象获取容器中多有的BeanDefinition信息
    */
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

我们发现这个接口中只有一个方法,传递了参数ConfigurableListableBeanFactory对象,代码中我们也解释了这个对象是什么。 问题是整个方法什么时候执行呢?

我们来看看springBean的加载流程图:
在这里插入图片描述
从图中我们可以看出来,spring 会加载我们编译好的Class文件,并且生成对应的BeanDefinition对象存储在缓存中,然后会根据这些BeanDefinition对象来创建对应的springBean,BeanFactoryPostProcessor就会在实例化之前执行。所以我们可以在实例化之前对bean的任何属性进行调整。

我们看一个案例: 我们在spring中注册Coder类,但是我们在实例化之前将Coder的类修改为Manager类,那么spring创建出来的coder对象应该就是Manager类的实例。 看代码:

准备两个Bean:

/**
 * @author 戴着假发的程序员
 * @company http://www.boxuewa.com
 * @description
 */
public class Coder{
    //构造方法
    public Coder(){
        System.out.println("实例化Coder对象");
    }
}
/**
 * @author 戴着假发的程序员
 * @company http://www.boxuewa.com
 * @description
 */
public class Manager {
    public Manager(){
        System.out.println("实例化Manager对象");
    }
}

自己定义一个BeanFactoryPostProcessor的实现类,在其中修改coder的class。

/**
 * @author 戴着假发的程序员
 * @company http://www.boxuewa.com
 * @description
 */
public class DkBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //获取coder的BeanDefinition对象
        BeanDefinition coder = beanFactory.getBeanDefinition("coder");
        //修改其class
        coder.setBeanClassName(Manager.class.getName());
    }
}

配置,在配置文件中配置我们的DkBeanFactoryPostProcessor,以及coder。注意不要配置Manager。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 配置我们的DkBeanFactoryPostProcessor -->
    <!-- 这里注意,我们只要将这个Bean交给spring即可,不需要id -->
    <bean class="com.igeek.dk.demo10.beanfactorypostprocessor.DkBeanFactoryPostProcessor"/>
    <!-- 正常配置colder -->
    <bean id="coder" class="com.st.dk.demo10.beans.Coder"/>
</beans>

测试,我们从容器中按照id取出coder,看看取出的对象是谁的实例:

 @Test
public void testBeanFactoryPostProcessor(){
    ApplicationContext ac =
            new ClassPathXmlApplicationContext("applicationContext-demo10.xml");
    Object coder = ac.getBean("coder");
    System.out.println("是否是Coder的实例:"+(coder instanceof Coder));
    System.out.println("是否是Manager的实例:"+(coder instanceof Manager));
}

结果:
在这里插入图片描述
我们会发现spring实例化的就是Manager对的实例,虽然我们配置的是Coder类型,但是实例化之前被我们使用BeanFactoryPostProcessor修改了类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

戴着假发的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值