4.3 容器13大模板方法之三:prepareBeanFactory(beanFactory)
【准备bean工厂】
//3、【准备bean工厂】为BeanFactory配置容器特性,例如类加载器、表达式解析器、注册默认环 境、后置管理器 prepareBeanFactory(beanFactory);
/1、设置 BeanFactory 的类加载器 //2、设置 BeanFactory 的表达式解析器 //3、设置 BeanFactory 的属性编辑器 //4、智能注册
tips
当前代码逻辑简单、且非核心
4.4 容器13大模板方法之四:postProcessBeanFactory(beanFactory)
【后置处理器Bean工厂】空方法
// 4、【后置处理器Bean工厂】此处为空方法,子类的实现 postProcessBeanFactory(beanFactory);
需要注意:
BeanFactoryPostProcessor和BeanPostProcessor,此处是前者
BeanFactoryPostProcessor 是容器级别的后处理器,对其他容器中的bean 没有影响
tips:子类实现skip当前方法
4.5 容器13大模板方法之五:invokeBeanFactoryPostProcessors()
【调用bean工厂后置处理器】
//调用顺序一:bean定义注册后置处理器 //调用顺序二:bean工厂后置处理器 //重点 //执行bean定义注册后置处理器!!!!!!!!!!!! //执行BeanF工厂后置处理器!!!!!!!!!!!!!!!!!!!!!!!!!!! public static void invokeBeanFactoryPostProcessors()
讲解重点(断点跟踪、类继承关系、架构图讲解)
关于invokeBeanFactoryPostProcessors为什么为true?
if (beanFactory instanceof BeanDefinitionRegistry) { ...略 }
找到核心逻辑
//164行 // 执行bean定义注册后置处理器!!!!!!!!!!!! invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //222行 //执行BeanF工厂后置处理器!!!!!!!!!!!!!!!!!!!!!!!!!!! invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
找到我们项目中的自定义两个处理器
进行断点追踪执行过程
com.spring.test.config.BeanDefinitionRegistryPostProcessorTest com.spring.test.config.BeanFactoryPostProcessorTest 此次代码略..........
tips
invoke方法近200行,只看核心
4.6 容器13大模板方法之六:registerBeanPostProcessors(beanFactory)
【注册bean后置处理器】
//6、【注册bean后置处理器】只是注册,但是不会反射调用 //功能:找出所有实现BeanPostProcessor接口的类,分类、排序、注册 registerBeanPostProcessors(beanFactory);
讲解重点(断点跟踪、类继承关系、架构图讲解)
//调用顺序一:bean定义注册后置处理器 //调用顺序二:bean工厂后置处理器 // 核心:查看重要的3步;最终目的都是实现bean后置处理器的注册 // 第一步: implement PriorityOrdered // 第二步: implement Ordered. // 第三步: Register all internal BeanPostProcessors.
4.7 容器13大模板方法之七:initMessageSource()
【初始化消息源】国际化问题i18n
//7、【初始化消息源】国际化问题i18n,参照https://nacos.io/ initMessageSource();
DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; //将这个messageSource实例注册到Bean工厂中 beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
关于beanFactory.registerSingleton( org.springframework.beans.factory.support.DefaultListableBeanFactory#registerSingleton将新建的这个bean手动注册到bean工厂步骤如下
调用:
org.springframework.beans.factory.support.DefaultListableBeanFactory#manualSingletonNames
这个集合器set中然后:先去一级缓存去找,没有,直接放到一级缓存。移除二级三级缓存
最后:设置bean公厂、放到集合
4.8 容器13大模板方法之八:initApplicationEventMulticaster()
【初始化应用程序事件多路广播】
//8、【初始化应用程序事件多路广播】初始化自定义的事件监听多路广播器,(观察 者)S initApplicationEventMulticaster();
tips:
需要理解观察者设计模式
重点:演示多播和容器发布
/** * 如果没有,则默认采用SimpleApplicationEventMulticaster行事件的广播 */ this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); //将多播注册到Bean工厂 beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
关于beanFactory.registerSingleton( org.springframework.beans.factory.support.DefaultListableBeanFactory#registerSingleton
将新建的这个bean手动注册到bean工厂
步骤如下
调用:
org.springframework.beans.factory.support.DefaultListableBeanFactory#manualSingletonNames
这个集合器set中
然后:先去一级缓存去找,没有,直接放到一级缓存。移除二级三级缓存
最后:设置bean公厂、放到集合
4.9 容器13大模板方法之九:onRefresh()
【刷新】 子实现:默认情况下不执行任何操作
// 9、【刷新】具体的子类可以在这里初始化一些特殊的 Bean(在初始化singleton beans 之前) onRefresh();
4.10 容器13大模板方法之十:registerListeners()
【注册所有监听器】
//10、【注册所有监听器】,监听器需要实现 ApplicationListener 接口。 registerListeners();
讲解重点(断点跟踪、类继承关系、架构图讲解)
//获取所有实现了ApplicationListener,然后进行注册 //查找顺序 //1、集合applicationListeners查找 //2、bean工厂找到实现ApplicationListener接口的bean //3、this.earlyApplicationEvents;准备刷新(启动第一步设置)
4.11 容器13大模板方法十一:finishBeanFactoryInitialization(beanFactory)
核心:【完成bean工厂初始化操作】
//11、 【完成bean工厂初始化操作】负责初始化所有的 singleton beans,反射生 成对象/填充 //此处开始调用Bean的前置处理器和后置处理器 finishBeanFactoryInitialization(beanFactory);
讲解重点(断点跟踪、类继承关系、架构图讲解)
//1、设置辅助器:例如:解析器、转换器、类装载器 //2、实例化(反射) //3、填充 //4、调用前置、后置处理器
//1、先从一级缓存拿(or 正在创建中),如果正在创建有,最后return null,说明此处为实例化 //2、在从二级缓存拿 //3、在从三级缓存拿 //以上三步为解决循环依赖 //4、getBean调用的时候,直接从一级缓存取出 @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { //先从一级缓存中拿,此处为空 Object singletonObject = this.singletonObjects.get(beanName); // 下面isSingletonCurrentlyInCreation的如果有值,即为true,说明当前线程是实例化 中... if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //在从二级缓存拿 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { //在从三级缓存拿 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
上面的代码总结:
先从一级缓存拿(此处如果为空,正在创建,直接return)为空,在从二级缓存拿还为空;在从三级缓存拿将三级缓存内容赋值给二级缓存
重点关注4个方法(重要)
调用时机:实例化(反射)对象/填充/回调后置(循环依赖&三级缓存)
调用入口:
xx.getBean()
容器初始化
getBean doGetBean createBean doCreateBean
实例化核心
org.springframework.beans.BeanUtils#instantiateClass(java.lang.reflect.Construct or<T>, java.lang.Object...)
注入核心
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#pop ulateBean
调用bean的前置、后置方法(这个时候bean已经实例化、注入完毕了)\
//注意: //1、先调用bean的前置处理器 //中间过程:调用bean的init方法或者实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法 //2、后调用bean的后置处理器
最后一次机会的回调(实例化后注入前)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#pop ulateBean ================================================================================ === boolean continueWithPropertyPopulation = true; //如果存在这实现这个接口的bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // postProcessAfterInstantiation如果返回 false,代表不需要进行后 续的属性设值 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } }
4.12 容器13大模板方法十二:finishRefresh()
【完成刷新】
protected void finishRefresh() { // 1、清除上下文级资源缓存 clearResourceCaches(); // 2、LifecycleProcessor接口初始化 // ps:当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明 的bean的周期做状态更新 // 而在LifecycleProcessor的使用前首先需要初始化 initLifecycleProcessor(); // 3、启动所有实现了LifecycleProcessor接口的bean //DefaultLifecycleProcessor,默认实现 getLifecycleProcessor().onRefresh(); // 4、发布上下文刷新完毕事件到相应的监听器 //ps:当完成容器初始化的时候, // 要通过Spring中的事件发布机制来发出ContextRefreshedEvent事件,以保证对应的监听 器可以做进一步的逻辑处理 publishEvent(new ContextRefreshedEvent(this)); // 5、把当前容器注册到到MBeanServer,用于jmx使用 LiveBeansView.registerApplicationContext(this); }
tips:
不重要
4.13 容器13大模板方法十三:resetCommonCaches()
【重设公共缓存】
//15、重设公共缓存 resetCommonCaches();
//清除内核缓存;因为我们的对象已经实例化并且注入完毕了 //中间过程数据(缓存)就不在需要了 protected void resetCommonCaches() { //清除之前声明过的方法和列的缓存 ReflectionUtils.clearCache(); //清除解析类型的缓存、序列化缓存 ResolvableType.clearCache(); //清除所有的类加载器 CachedIntrospectionResults.clearClassLoader(getClassLoader()); }