前言
Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点。两个接口从名字看起来很相似,但是作用及使用场景却不同。
前面我们已经大致了解了BeanPostProcessor的作用,可以点击spring源码阅读之BeanPostProcessor
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。
注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
其实我可以简单高度概括一下: BeanFactoryPostProcessor <---------对应修改-----------> BeanDefinition
BeanPostProcessor <---------对应修改-----------> Bean
源码
public interface BeanFactoryPostProcessor {
/**
* spring 的扩展点之一
* 实现该接口,可以在spring的bean创建之前修改bean的定义属性
* spring运行BeanfactoryPostoryProceesor 在容器实例化任何其他bean之前读取配置云数据,
* 并可以根据需要进行修改,例如可以把bean的scop从singleton修改成为prototypo,也可以吧吧property的值给改掉
* 可以同时配置多个BeanFactoryPostoProcessor,并通过"order"属性来控制各个BeanFactoryPostProcessor的执行顺序,
* BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的
* 可以写一个离职来测试这个功能
*/
/**
* 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;
}
自定义beanFactoryPostProcessor
package com.wfg.beanfactorypostprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* spring
*
* @Title: com.wfg.beanfactorypostprocessor
* @Date: 2021/1/1 0001 21:49
* @Author: wfg
* @Description:
* @Version:
*/
@Component
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("====postProcessBeanFactory====");
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName:beanDefinitionNames ) {
System.out.println("beanName : "+beanName);
if("userDaoImpl".equals(beanName)){
BeanDefinition userDaoImpl = beanFactory.getBeanDefinition(beanName);
userDaoImpl.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
}
}
}
}
测试
public class TestUserDao {
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
//configApplicationContext.register(UserDaoImpl.class);
//configApplicationContext.refresh();
UserDao bean = configApplicationContext.getBean(UserDaoImpl.class);
UserDao bean1 = configApplicationContext.getBean(UserDaoImpl.class);
System.out.println(bean.hashCode()+"======="+bean1.hashCode());
bean.query();
}
}
发现hashcode不一致说明不是同一个对象了
在Spring中内置了一些BeanFactoryPostProcessor实现类:
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
org.springframework.beans.factory.config.PropertyOverrideConfigurer
org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器