BeanFactoryPostProcessor
是 Spring 中 Bean 工厂的后置处理器,她在 Spring 加载了 Bean 的定义文件后,在 Bean 实例化之前执行。所以,当我们实现了这个接口,就可以修改整个 Bean 工厂的 Bean 的一些属性,比如,修改 Bean 的作用域,设置 despendsOn,设置是否懒加载等等。
@ComponentScan("com.javahly.spring44")
public class Appconfig {
}
@Component
public class IndexService {
}
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition indexService = beanFactory.getBeanDefinition("indexService");
//默认是单例,这里我们把单例 Bean修改成原型Bean
indexService.setScope("prototype");
}
}
public class Test {
public static void main(String[] args){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Appconfig.class);
//输出的是原型
System.out.println(applicationContext.getBean("indexService"));
System.out.println(applicationContext.getBean("indexService"));
System.out.println(applicationContext.getBean("indexService"));
}
}
而且,我们可以实现多个 BeanFactoryPostProcessor,通过 order 属性顺序执行。
@Component
public class MyBeanFactoryPostProcessor1 implements BeanFactoryPostProcessor,Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition indexService = beanFactory.getBeanDefinition("indexService");
//把单例修改成原型
indexService.setScope("prototype");
System.out.println("BeanFactoryPostProcessor1");
}
//数值越小,月优先执行
@Override
public int getOrder() {
return 0;
}
}
@Component
public class MyBeanFactoryPostProcessor2 implements BeanFactoryPostProcessor,Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition indexService = beanFactory.getBeanDefinition("indexService");
//把单例修改成原型
indexService.setScope("singleton");
System.out.println("BeanFactoryPostProcessor2");
}
@Override
public int getOrder() {
return 1;
}
}
我们是先执行 1,再执行 2,我们先把单例改成了原型,再把原型改成了单例。
总结
在我们开发中,如果我们想动态地对 BeanDefinition 进行修改,我们就可以实现这个接口,这是 Spring 的扩展点之一。Spring内部也有一个核心的类 ConfigurationclassPostProcessor
调用 postProcessBeanFactory 这个方法对加了 @Configuration 实现了动态代理,不过ConfigurationclassPostProcessor 是实现了 BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor
,BeanDefinitionRegistryPostProcessor 是对 BeanFactoryPostProcessor的扩展,功能更强,也是Spring 的扩展点之一,下面的文章会讲到。
ABOUT
公众号:【星尘Pro】
github:https://github.com/huangliangyun