Spring注解驱动之BeanFactoryPostProcessor原理解析
在Spring中,BeanFactoryPostProcessor是Spring IoC容器提供的一个扩展点,它可以在Bean被实例化之前,对Bean进行改变或者增强。本文就详细介绍一下BeanFactoryPostProcessor的原理以及示例说明。
BeanFactoryPostProcessor的原理
BeanFactoryPostProcessor接口
BeanFactoryPostProcessor是Spring IoC容器提供的拓展接口,其定义代码如下:
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
通过实现这个接口的Bean,可以在IoC容器实例化所有的Bean之后,在Bean初始化之前对Bean进行额外的处理操作。
BeanFactoryPostProcessor的作用
BeanFactoryPostProcessor的作用主要是对IoC容器中的Bean进行后置处理,最常见的是修改BeanDefinitionRegistry中的BeanDefinition,对动态注入Bean的属性进行自定义设置。
举个例子,假如我们需要动态注入一个dataSource,在传递dataSource的属性时,我们需要将它的url、userName、password三个属性值都进行加密,那么我们可以通过实现BeanFactoryPostProcessor接口,在Bean实例化之前,对dataSource属性的值进行修改。
BeanFactoryPostProcessor的执行顺序
BeanFactoryPostProcessor拥有一个优先级的概念,这批处理器的执行顺序是由优先级来决定。
默认情况下,Spring容器中有两个内置的BeanFactoryPostProcessor:ConfigurationClassPostProcessor和AutowiredAnnotationBeanPostProcessor,在容器创建BeanFactory之后立即执行。
BeanFactoryPostProcessor的执行过程
它的执行过程在IoC容器的实例化时期之前。具体执行过程如下:
- IoC容器创建 BeanFactory 实例
- IoC容器实例化Spring内置的 BeanFactoryPostProcessor,执行postProcessBeanFactory()方法
- IoC容器执行注册的 BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry()方法,通常这步是自定义添加BeanFactoryPostProcessor的地方
- IoC容器实例化预处理的 BeanPostProcessor,执行postProcessBeforeInitialization()方法
- IoC容器实例化Bean实例
- IoC容器执行后处理的 BeanPostProcessor,执行postProcessAfterInitialization() 方法
示例说明
示例一
自定义一个BeanFactoryPostProcessor实现类,实现对BeanDefinition对象中的scope属性修改。
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
if (beanDefinition.getScope().equals(ConfigurableBeanFactory.SCOPE_SINGLETON)) {
beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
}
}
}
}
然后我们在Spring配置文件中加入定义该处理器:
<bean class="com.example.MyBeanFactoryPostProcessor" />
定义一个单例Bean,因为我们在处理器实现的方法中将单例Bean修改为了多例Bean。
<bean id="helloWorld" class="com.example.HelloWorld" />
最后输出打印出来Bean对应的scope,如果输出的是prototype,则意味着我们的BeanFactoryPostProcessor已经生效。
示例二
自定义一个BeanFactoryPostProcessor实现类,将Bean属性的值设置为当前时间。
public class DateBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
PropertyValues pvs = beanDefinition.getPropertyValues();
MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
mutablePropertyValues.addPropertyValue("date", new Date());
pvs.addPropertyValue(mutablePropertyValues);
}
}
}
然后我们在Spring配置文件中加入定义该处理器,并设置要注入的Bean的属性值:
<bean class="com.example.DateBeanFactoryPostProcessor" />
<bean id="date" class="java.util.Date" />
<bean id="testBean" class="com.example.TestBean">
<property name="date" ref="date" />
</bean>
最后输出打印出来Bean属性对应的date值,如果输出的是当前时间,则意味着我们的BeanFactoryPostProcessor已经生效。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring注解驱动之BeanFactoryPostProcessor原理解析 - Python技术站