1. 前言
读spring源码的时候,在AbstractApplicationContext类中有这样的代码,不知道啥意思,特学习并记录一下
源代码如下:
2. postProcessBeanFactory(beanFactory)
这个是spring在启动时,加载完所有的BeanDefinition,并且BeanFactory刚刚准备好,BeanFactory里面的bean都还没有被实例化的时候执行,是spring留给我们做扩展,可以在BeanFactory刚加载,但还没实例化bean时,做一些额外处理,比如:修改BeanFactory中的内容,打印BeanFactory里的信息等
package com.wz;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author WangZhen
* @Date 2024/3/11 21:37
*/
public class TestForPostProcessBeanFactory {
public static void main(String[] args) {
// new一个AnnotationConfigApplicationContext的子类,实现其postProcessBeanFactory方法做演示
// 演示结果可知,在postProcessBeanFactory方法中,可以获取beanFactory的信息,也可以修改其中的BeanDefinition, 是一个很强大的扩展接口
ApplicationContext context2 = new AnnotationConfigApplicationContext("com.wz"){
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("------------------------------------------");
System.out.println("------------------------------------------");
System.out.println("------------------------------------------");
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
System.out.println("BeanFactory初始时,加载了以下BeanFactory");
for (String beanDefinitionName : beanDefinitionNames) {
// 这里不能调用getBean方法,调用了,就会触发bean的实例化操作,为了演示,先不调用
// Object bean = beanFactory.getBean(beanDefinitionName);
// System.out.println(beanDefinitionName + "===>" + bean.getClass().getName());
System.out.println(beanDefinitionName);
}
// 获得名字叫person的bean, 并修改其属性
beanFactory.getBeanDefinition("person").setPrimary(true);
System.out.println("------------------------------------------");
System.out.println("------------------------------------------");
System.out.println("------------------------------------------");
}
};
}
}
运行结果:
3. BeanFactoryPostProcessor
该类是一个接口,而且是一个函数式接口
源码:
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 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;
}
该接口的作用和上面第二点是一样的,都可以访问BeanFactory, 访问时期也差不多,
不过是先执行上面的 postProcessorBeanFactory() 方法,再执行下面的 invokeBeanFactoryPostProcessors方法,从上图源码中可以看出来
public class TestForInvokeBeanFactoryPostProcessors {
public static void main(String[] args) {
// new一个AnnotationConfigApplicationContext的子类,实现其postProcessBeanFactory方法做演示
// 演示结果可知,在postProcessBeanFactory方法中,可以获取beanFactory的信息,也可以修改其中的BeanDefinition, 是一个很强大的扩展接口
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext("com.wz");
context2.addBeanFactoryPostProcessor((beanFactory -> {
System.out.println("---------------6666----------------");
Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
System.out.println("----------------666---------------");
}));
}
}