Spring应用手册-BeanFactoryPostProcessor接口
程序员文章站
2024-03-24 16:01:28
...
戴着假发的程序员出品 抖音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修改了类型。
推荐阅读
-
Spring应用手册-BeanFactoryPostProcessor接口
-
Spring应用手册-DisposableBean接口
-
Spring应用手册-InitializingBean接口
-
Spring应用手册-BeanPostProcessor接口
-
Spring的BeanFactoryPostProcessor接口示例代码详解
-
Spring应用手册--FactoryBean接口
-
Spring的BeanFactoryPostProcessor接口
-
springboot原理实战(3)-- spring扩展接口BeanPostProcessor,BeanFactoryPostProcessor
-
Gstreamer应用开发手册7:接口、时钟与同步
-
Spring应用手册--FactoryBean接口