Spring ioC源码深入剖析Bean的实例化 2

简介: Spring ioC源码深入剖析Bean的实例化
+关注继续查看

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) {
...略
}

image

找到核心逻辑

//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公厂、放到集合image

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());
}


目录
相关文章
|
5天前
|
Java C# Spring
Spring中Bean实例化过程中的initializeBean方法
Spring中Bean实例化过程中的initializeBean方法
26 0
|
5天前
|
Java Spring
Spring中那些BeanPostProcessor在Bean实例化过程中的作用
Spring中那些BeanPostProcessor在Bean实例化过程中的作用
33 1
|
28天前
|
Java Spring 容器
Spring中Bean实例化过程中的populateBean方法
Spring中Bean实例化过程中的populateBean方法
17 0
|
3月前
|
XML Java 数据格式
spring是如何实例化bean的?spring实例化bean有哪些方式
spring是如何实例化bean的?spring实例化bean有哪些方式
|
3月前
|
XML Java 数据格式
Spring ioC源码深入剖析Bean的实例化 1
Spring ioC源码深入剖析Bean的实例化
25 0
|
4月前
|
Java 数据安全/隐私保护 Spring
【Spring】Bean 的实例化(创建 | 获取)
【Spring】Bean 的实例化(创建 | 获取)
|
5月前
|
Java 容器 Spring
七.Spring源码剖析-Bean的实例化-属性注入
喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 这一章节我们来讨论创建Bean过程中的属性注入,在Spring的IOC容器启动过程中,会把定义的Bean封装成BeanDefinition注册到一个ConcurrentHashMap中,Bean注册完成后,就会对单利的且lazy-init=false 的Bean进行实例化。创建Bean的代码在 AbstractAutowireCapableBeanFactory#doCreateBean 中,当Bean创建成功之后,会调用AbstractAutowireCapableBeanFactory#populat
|
5月前
|
存储 缓存 Java
六.Spring源码剖析-单利Bean的实例化
前面系列章节我们分析了Spring的IOC的启动流程,包括:容器创建,配置加载,配置解析,Bean注册等几个阶段,所以Bean注册其实就是把Bean的相关属性,依赖关系等封装成BeanDeafinition对象,然后注册到一个ConcurrentHashMap中。要注意的是这个BeanDeafinition只是对Bean的一个定义封装而已,并不是真正的Bean的实例,那Bean的实例是在什么时候创建的?有三种情况 如果是单利Bean,且lazy-init=false 急切初始(即时,立即,迫切,饥饿都是一个意思)的情况,在IOC容器启动之后就会根据BeanDeafinition对Bean进行
|
5月前
|
缓存 Java Spring
讲解 Spring 实例化的不同方式及相关生命周期源码剖析(三)
讲解 Spring 实例化的不同方式及相关生命周期源码剖析(三)
41 0
|
5月前
|
XML 缓存 Java
讲解 Spring 实例化的不同方式及相关生命周期源码剖析(二)
讲解 Spring 实例化的不同方式及相关生命周期源码剖析(二)
37 0
热门文章
最新文章
相关产品
云迁移中心
推荐文章
更多