39、扩展原理-BeanFactoryPostProcessor
- BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
- BeanFactoryPostProcessor:beanFactory的后置处理器;
- 在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
- 所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
BeanFactoryPostProcessor原理:
- ioc容器创建对象
- invokeBeanFactoryPostProcessors(beanFactory);
- 如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
- 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
- 在初始化创建其他组件前面执行
- 如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
BeanFactoryPostProcessor
代码测试
package com.suirui.springanno.ext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryProcessor _____postProcessBeanFactory running");
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
//此处的getBean就是之前那流程,getBean->doGetBean-> getSingleton(第一次尝试拿到bean拿到就包装一下返回)
// ->getSingleton(第二次lamda表达式创建bean)->createBean->此时bean有两种方式,首先可能的话,返回一个bean的Proxy代理类(resolveBeforeInstantiation,其实是调用了实现了)
// ->没有Proxy则调用doCreateBean创建bean->populateBean实现bean的创建->initializeBean实现bean的初始化(beforeinitialize,initialize,postinitialize)->完成注册
MyBeanFactoryProcessor myBeanFactoryProcessor = (MyBeanFactoryProcessor) beanFactory.getBean("myBeanFactoryProcessor");
myBeanFactoryProcessor.demo();
}
public void demo(){
System.out.println("Demo");
}
}
package com.suirui.springanno.ext;
import com.suirui.springanno.ext.config.ExtConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTestExt {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ExtConfig.class);
}
}
源码分析
创建IOC容器,刷新容器
invokeBeanFactoryPostProcessors(beanFactory)
下面我们看一下invokeBeanFactoryPostProcessors(beanFactory)方法里面做了什么操作