目录
- 前言
- 阅读准备
- 阅读指引
- 阅读建议
- 课程内容
- 一、SpringIOC之实例化
- 1.1 简单回顾
- 1.2 概念回顾
- 1.3 核心方法讲解
- 二、方法讲解
- 2.1 AbstractBeanFactory#getMergedLocalBeanDefinition:合并BeanDefinition
- 2.2 AbstractAutowireCapableBeanFactory#createBean:创建Bean
- 2.3 AbstractAutowireCapableBeanFactory#resolveBeanClass:加载类
- *2.4 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:实例化前
- 2.5 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation:【实例化前】真正干活的地方
- 2.6 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization:第一次可能调用【初始化后】
- 2.7 AbstractAutowireCapableBeanFactory#doCreateBean:开始实例化(包括后续的实例化过程)
- 2.8 AbstractAutowireCapableBeanFactory#createBeanInstance:实例化
- 2.9 AbstractAutowireCapableBeanFactory#autowireConstructor:推断构造方法
- 2.10 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors:BeanDefinition后置处理
- 2.11 AbstractAutowireCapableBeanFactory#populateBean:属性注入
- 三、实例化逻辑流程图
- 学习总结
前言
阅读准备
由于Spring源码分析是一个前后联系比较强的过程,而且这边分析,也是按照代码顺序讲解的,所以不了解前置知识的情况下,大概率没办法看懂当前的内容。所以,特别推荐看看我前面的文章(自上而下次序):
- Spring底层核心原理解析【学习难度:★★☆☆☆】
- 手写简易Spring容器过程分析【学习难度:★★☆☆☆】
- Spring之底层架构核心概念解析【学习难度:★★★☆☆,重要程度:★★★★★】
- Bean的生命周期流程图【学习难度:☆☆☆☆☆,重要程度:★★★★★】
- Spring之Bean的生命周期源码解析——阶段一(扫描生成BeanDefinition)
(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)
(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)
(PS:特别是《Bean的生命周期流程图》,帮大家【开天眼】,先了解下流程。毕竟【通过业务了解代码,远比通过代码了解业务简单的多】!!!!)
阅读指引
我们在上一节课已经说到过了,本次Spring源码剖析的总入口是new AnnotationConfigApplicationContext("org.tuling.spring");
,这里就不再重复解释了。本节课要说的内容,是SpringIOC的实例化,我们这里直接给到入口吧,调用链如下:(调用链比较深,不要纠结细枝末节)
- AbstractApplicationContext#refresh:刷新方法,不用在意
- AbstractApplicationContext#finishBeanFactoryInitialization:在这里实例化所有剩余的(非lazy-init)单例
- DefaultListableBeanFactory#preInstantiateSingletons:在这里实例化所有剩余的(非lazy-init)单例(上面的方法,核心干活的方法就是这里)
- DefaultListableBeanFactory#getBean:获取Bean的方法
- AbstractBeanFactory#doGetBean:返回指定bean的一个实例,它可以是共享的,也可以是独立的
- 上面这个
AbstractBeanFactory#doGetBean
里面的一段局部代码写的回调方法,如下:
// 如果是单例创建bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
- AbstractAutowireCapableBeanFactory#createBean:这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等。
如上面的调用链所示,最后一个方法,才是我们本次要研究的核心方法。而且通过注释,我想大家也看到了,这个方法不单单干了实例化的工作,还有属性填充、各种后置处理器等。(PS:哈哈,同学们,我知道这个【实例化】调用链挺深的,但是大家不要烦恼,只要切记【不要纠结那些细枝末节】那一切都OK,我们老老实实地跟着主线来研究就好,毕竟这些才是核心)
阅读建议
- 看源码,切记纠结细枝末节,不然很容易陷进去。正常来说,看主要流程就好了
- 遇到不懂的,多看看类注释或者方法注释。Spring这种优秀源码,注释真的非常到位
- 如果你是idea用户,多用F11的书签功能。
- Ctrl + F11 选中文件 / 文件夹,使用助记符设定 / 取消书签 (必备)
- Shift + F11 弹出书签显示层 (必备)
- Ctrl +1,2,3…9 定位到对应数值的书签位置 (必备)
课程内容
一、SpringIOC之实例化
1.1 简单回顾
大家知道,实例化的过程是怎样的吗?哈,我知道大部分的同学可能都不会知道。所以呢,我希望大家真的要有去看过《 Bean的声明周期流程图》,因为,通过【代码去理解业务】,远远比【通过业务理解代码】难得多!直接看个图吧,起码咱得知道【实例化到底干了什么,有哪些步骤】,我们才能更好的去研究。
如上图所示,实例化包含了:合并BeanDefinition、加载类、实例化之前、推断构造方法、实例化、BeanDefinition的后置处理、实例化后等,这些关键步骤。这就是我们本篇文章研究的核心!!
1.2 概念回顾
在这个【实例化】过程中,涉及到了一些Spring底层设计的概念,我在上一个笔记里面有大概介绍过Spring底层概念的一些讲解,不记得的同学记得回去翻一翻。
主要涉及的概念有:
- BeanDefinition(设计图纸):BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特征
- BeanPostProcessor(Spring重要的拓展点):Bean的后置处理器,对Bean做拓展操作。我们前面说过,
BeanPostProcessor
提供了【初始化前/后】两个拓展方法。但是这里,Spring内部对这个接口做了很多拓展,新增了一些继承自BeanPostProcessor
的子类或者子接口。在实例化阶段,主要用到的接口如下:InstantiationAwareBeanPostProcessor
,直译过来就是:能感知实例化的Bean后置处理器。而这个继承自BeanPostProcessor
,显然也具备这【初始化前/后】两个拓展方法。另外,通过InstantiationAwareBeanPostProcessor
的名字大家也能猜到了,它肯定是具有对【实例化】阶段拓展的能力的。接口定义在后面。SmartInstantiationAwareBeanPostProcessor
:直译过来就是:智能的,能感知实例化的Bean后置处理器。在这个接口中,拓展了InstantiationAwareBeanPostProcessor
接口,新增了几个函数,其中就包括了推断构造的实现。另外,这是一个框架内部使用接口。接口定义在后面。MergedBeanDefinitionPostProcessor
:直译过来就是:合并BeanDefinition的后置处理器。运行时用于合并bean定义的后处理器回调接口。接口定义在后面。
InstantiationAwareBeanPostProcessor接口定义如下:
/**
* BeanPostProcessor的子接口,用于添加实例化前回调,以及实例化后但显式属性设置或自动生成之前的回调。
* 通常用于抑制特定目标bean的默认实例化,例如创建具有特殊TargetSources的代理(池化目标、惰性初始化目标等),或者实现额外的注入策略,如字段注入。
* 注:此接口为专用接口,主要供框架内部使用。建议尽可能实现普通的BeanPostProcessor接口。
* 自:
* 1.2
* 参见:
* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.setCustomTargetSourceCreators, org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator
* 作者:
* 于尔根·霍勒,罗德·约翰逊
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在目标bean实例化之前应用这个BeanPostProcessor。返回的bean对象可能是要使用的代理而不是目标bean,从而有效地抑制目标bean的默认实例化。
* 如果此方法返回一个非空对象,则bean创建过程将会中断。应用的唯一进一步处理是来自配置的BeanPostProcessors的postProcessAfterInitialization回调。
* 这个回调将应用于带有bean类的bean定义,以及工厂方法定义,在这种情况下,返回的bean类型将在这里传递。
* 后置处理器可以实现扩展的SmartInstantiationAwareBeanPostProcessor接口,以便预测它们将在这里返回的bean对象的类型。
* 默认实现返回null。
* 参数:
* beanClass——要实例化的bean的类
* beanName—bean的名称
* 返回:
* 要公开的bean对象,而不是目标bean的默认实例,或者为空,继续进行默认实例化
* 抛出:
* BeansException -在错误的情况下
* 参见:
* postProcessAfterInstantiation, org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClass(), org.springframework.beans.factory.support.AbstractBeanDefinition.getFactoryMethodName()
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 在bean通过构造函数或工厂方法实例化之后,但在Spring属性填充(来自显式属性或自动装配)发生之前执行操作。
* 这是在Spring自动装配开始之前对给定bean实例执行自定义字段注入的理想回调。
* 默认实现返回true。
* 参数:
* Bean—已创建的Bean实例,其属性尚未设置
* beanName—bean的名称
* 返回:
* 如果应该在bean上设置属性,则为True;如果应该跳过属性人口,则为False。正常的实现应该返回true。返回false还将阻止在此bean实例上调用任何后续的InstantiationAwareBeanPostProcessor实例。
* 抛出:
* BeansException -在错误的情况下
* 参见:
* postProcessBeforeInstantiation
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* 在工厂将给定的属性值应用到给定的bean之前,对它们进行后处理,不需要任何属性描述符。
* 如果实现提供自定义postProcessPropertyValues实现,则应该返回null(默认值),否则则返回pvs。在该接口的未来版本中(删除了postProcessPropertyValues),默认实现将直接返回给定的pv。
* 参数:
* PVS—工厂将要应用的属性值(永远不会为空)
* bean——已创建的bean实例,但其属性尚未设置
* beanName—bean的名称
* 返回:
* 应用于给定bean的实际属性值(可以是传入的PropertyValues实例),或者null,它继续处理现有属性,但特别地继续调用postProcessPropertyValues(需要为当前bean类初始化PropertyDescriptors)。
* 抛出:
* BeansException -在错误的情况下
* 自:
* 5.1
* 参见:
* postProcessPropertyValues
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* 在工厂将给定属性值应用到给定bean之前,对它们进行后处理。允许检查是否满足所有依赖项,例如基于bean属性设置器上的“Required”注释。
* 还允许替换要应用的属性值,通常通过基于原始PropertyValues创建新的MutablePropertyValues实例,添加或删除特定值。
* 默认实现按原样返回给定的pv。
* 弃用
* 从5.1开始,支持postProcessProperties(PropertyValues, Object, String)
* 参数:
* PVS—工厂将要应用的属性值(永远不会为空)
* PDS——目标bean的相关属性描述符(忽略了依赖类型——工厂专门处理的依赖类型——已经过滤掉了)
* bean——已创建的bean实例,但其属性尚未设置
* beanName—bean的名称
* 返回:
* 应用于给定bean的实际属性值(可以是传入的PropertyValues实例),或者为null以跳过属性填充
* 抛出:
* BeansException -在错误的情况下
* 参见:
* postProcessProperties, org.springframework.beans.MutablePropertyValues
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
SmartInstantiationAwareBeanPostProcessor接口定义如下:
/**
* 扩展了InstantiationAwareBeanPostProcessor接口,添加了一个回调函数,用于预测被处理bean的最终类型。
* 注:此接口为专用接口,主要供框架内部使用。一般来说,应用程序提供的后处理器应该简单地实现普通的BeanPostProcessor接口,或者从InstantiationAwareBeanPostProcessorAdapter类派生。即使在点发布版本中,也可能向该接口添加新方法。
* 自:
* 2.0.3
* 参见:
* InstantiationAwareBeanPostProcessorAdapter
* 作者:
* Juergen hoel
*/
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 预测这个处理器的postProcessBeforeInstantiation回调最终返回的bean的类型。
* 默认实现返回null。
* 参数:
* beanClass—bean的原始类beanName—bean的名称
* 返回:
* bean的类型,如果不可预测,则为空
* 抛出:
* BeansException -在错误的情况下
*/
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 确定要为给定bean使用的候选构造函数。
* 默认实现返回null。
* 参数:
* beanClass—bean的原始类(不为空)beanName—bean的名称
* 返回:
* 候选构造函数,如果未指定,则为空
* 抛出:
* BeansException -在错误的情况下
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 获取对指定bean的早期访问的引用,通常是为了解析循环引用。
* 这个回调让后处理器有机会尽早公开包装器——也就是说,在目标bean实例完全初始化之前。暴露的对象应该等同于postProcessBeforeInitialization / postProcessAfterInitialization所暴露的对象。请注意,此方法返回的对象将用作bean引用,除非后处理器返回与所述后处理回调不同的包装器。换句话说:那些处理后回调可能最终公开相同的引用,或者返回那些后续回调的原始bean实例(如果受影响的bean的包装器已经为对该方法的调用构建了,那么默认情况下它将作为最终bean引用公开)。
* 默认实现按原样返回给定的bean。
* 参数:
* bean—原始bean实例beanName—bean的名称
* 返回:
* 要作为bean引用公开的对象(通常将传入的bean实例作为默认值)
* 抛出:
* BeansException -在错误的情况下
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
MergedBeanDefinitionPostProcessor接口定义如下:
/**
* 运行时用于合并bean定义的后处理器回调接口。BeanPostProcessor实现可以实现这个子接口,以便对合并的bean定义(原始bean定义的处理副本)进行后处理,Spring BeanFactory使用合并的bean定义来创建bean实例。
* 例如,postProcessMergedBeanDefinition方法可以对bean定义进行内省,以便在对bean的实际实例进行后处理之前准备一些缓存的元数据。也允许修改bean定义,但只允许修改用于并发修改的定义属性。本质上,这只适用于在RootBeanDefinition本身上定义的操作,而不适用于其基类的属性。
* 自:
* 2.5
* 参见:
* org.springframework.beans.factory.config.ConfigurableBeanFactory.getMergedBeanDefinition
* 作者:
* Juergen hoel
*/
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* 对指定bean的给定合并bean定义进行后处理。
* 参数:
* beanDefinition—为bean合并的bean定义beanType—托管bean实例的实际类型beanName—bean的名称
* 参见:
* AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* 通知指定名称的bean定义已被重置,并且此后处理器应清除受影响bean的所有元数据。
* 默认实现为空。
* 参数:
* beanName—bean的名称
* 自:
* 5.1
* 参见:
* DefaultListableBeanFactory.resetBeanDefinition
*/
default void resetBeanDefinition(String beanName) {
}
}
这里还是有一点想要提醒各位的,BeanPostProcessor
是被Spring定义为【钩子】的,而钩子,很多时候都是为了改变系统原有行为的。这种改变,通常体现在:对Bean生命周期的影响,或者某个生命周期完成对象的改变等等。(这么说有点晦涩难懂,通俗点讲就是:Bean可能不会经过完整生命周期,比如【实例化前】之后,直接就跳到【初始化后】了,没有经过原本定义的【实例化】、【实例化后】、【其他后置处理】等;或者,原本初始化动作是Spring帮我门完成的,但是由于我们自己介入了,Spring就不帮我们初始化了,而是按照程序员意愿)
文章链接:
《【Spring专题】Spring之底层架构核心概念解析》
1.3 核心方法讲解
整个IOC实例化的主干过程,主要涉及了【2个类,11个核心方法】。下面,我们将会按照调用次序,依次讲解各个方法。
二、方法讲解
我们在上面说到过,这里的实例化过程包含了:合并BeanDefinition、加载类、实例化之前、推断构造方法、实例化、BeanDefinition的后置处理、实例化后等关键步骤。所以,在整个调用链上,基本上就是干了这些事情。
我们前面说过,本次的实例化代码入口如下:
// 如果是单例创建bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
2.1 AbstractBeanFactory#getMergedLocalBeanDefinition:合并BeanDefinition
方法调用链:AbstractBeanFactory#doGetBean里面调用的
全路径:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
方法注释:返回合并的RootBeanDefinition,如果指定的bean对应于子bean定义,则遍历父bean定义。
我们在上节课最后的地方提到过这个,这边就不重复讲了,但是,他是算在实例化过程里面的,嘻嘻
2.2 AbstractAutowireCapableBeanFactory#createBean:创建Bean
方法调用链:AbstractBeanFactory#doGetBean里面调用的
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
方法注释:这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等。
源码如下:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 步骤一:加载类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 不用管这个
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 步骤二:实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 步骤三:创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
方法解读:上面代码老长一段,trt-catch
占了一半,啊哈哈。 这里面的步骤就三个,下面也会讲到。
- resolveBeanClass:加载类
- resolveBeforeInstantiation:实例化前
- doCreateBean:真正创建Bean的地方
2.3 AbstractAutowireCapableBeanFactory#resolveBeanClass:加载类
PS:不算很重要,知道有这个步骤就好
方法调用链:由2.2的createBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeanClass
方法注释:这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等。
源码如下:
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
方法解读:这个代码外层挺简单的,也许大家对比System.getSecurityManager() != null
这个比较难理解而已。这是Spring内部的一个安全管理器,很多时候都是不开启的。后面也会出现大量这种代码,反正遇到这个就直接看else
的逻辑就好了。至于里层的doResolveBeanClass
源码如下:
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
// 步骤一:获取默认的类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
// 步骤二:在我们这个调用链上不会走这里,因为typesToMatch为null
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
// 步骤三
String className = mbd.getBeanClassName();
if (className != null) {
// 步骤3.1:这里也不用怎么看,这是Spring表达式解析的东西。Spring表达式这个东西我们用的很少(类似EL表达式,这样来理解)
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
if (dynamicLoader != null) {
try {
// 步骤3.2 加载类
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// 步骤四:正常来说走的是这里。使用默认的类加载器加载类
return mbd.resolveBeanClass(beanClassLoader);
}
方法解读:在这里,大体分为4个步骤。步骤一就是获取类加载器。这个获取类加载器的原则呢,是这样的:
- 优先返回当前线程中的ClassLoader
- 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
- 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
步骤二,就是第一个if
,在我们这里的调用链上是不会进来这里的,因为typeToMatch
是null;
步骤三,可看可不看,一般也不会进来这里。这是Spring表达式解析的东西。Spring表达式这个东西我估计大部分人都没用过吧…(类似EL表达式,这样来理解)
步骤四,正常来说会执行到这里,然后在这里进行类加载,并且通过反射获得class对象,代码如下所示:
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}
*2.4 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:实例化前
(PS:终于来到这里了,这才是核心考点)
方法调用链:由2.2的createBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
方法注释:应用实例化前的后处理器,解析指定bean是否存在实例化前的快捷方式。
源码如下:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
方法解读:代码短短的几行。首先通过hasInstantiationAwareBeanPostProcessors
看看是否有InstantiationAwareBeanPostProcessors
。有,则调用对应的【实例化前】方法,即applyBeanPostProcessorsBeforeInstantiation
(这里才是真正干活的地方,后面介绍)。
这里有一个细节,那就是applyBeanPostProcessorsBeforeInstantiation
如果返回的对象不为空,则直接调用applyBeanPostProcessorsAfterInitialization
,走bean的【初始化后】方法了!这啥意思???说明,==Bean的生命周期被改变了!!==而且,如果这里的Bean有值的话,外层直接返回创建成功了,不会继续往下走了,如下所示:(2.2的createBean调用处代码)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
2.5 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation:【实例化前】真正干活的地方
方法调用链:由2.4的resolveBeforeInstantiation调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
方法注释:将InstantiationAwareBeanPostProcessors应用到指定的bean定义(通过类和名称),调用它们的postProcessBeforeInstantiation方法。如果返回不为空,则无需Spring帮我们实例化了
源码如下:
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
方法解读:这里终于出现我们之前说的核心InstantiationAwareBeanPostProcessor
了。老样子,遍历所有的InstantiationAwareBeanPostProcessor
,然后调用postProcessBeforeInstantiation()
。这里只要找到一个InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation()
返回不为空,则直接停止遍历。
这个方法其实隐含的意思是:在Spring帮我们实例化之前,Spring会先去找找看,用户有没有对当前beanName对应的class有自己的实例化想法,如果有,则Spring就不帮我们创建了。
2.6 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization:第一次可能调用【初始化后】
方法调用链:由2.4的resolveBeforeInstantiation调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
方法注释:应用初始化后方法。通常调用此方法的时候,会认为已经经过了属性填充、初始化等
源码如下:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
方法解读:看,这里直接获取所有BeanPostProcessor
接口,然后应用postProcessAfterInitialization()
方法。这里有个空判断,是接口要求这么做的。返回null表示不想继续执行剩余的BeanPostProcessor
接口
2.7 AbstractAutowireCapableBeanFactory#doCreateBean:开始实例化(包括后续的实例化过程)
方法调用链:由2.2的createBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
方法注释:AbstractAutowireCapableBeanFactory这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等
源码很长,就不截取了。在这里个方法里面,主要干了4件事情:
- 实例化(推断构造方法、实例化)
- BeanDefinition的后置处理
- 属性注入(实例化后、属性注入)(对的,你没看错,【实例化后】是在属性注入这个方法里面被调用的)
- 初始化
方法解读:正如方法注释说的,这里【创建一个bean实例,填充bean实例,应用后处理器】等等。这意味着,在这里包含了【实例化】过程中剩余的==【推断构造方法、实例化、BeanDefinition的后置处理、实例化后等】==步骤。另外,下一个章节会说的【IOC属性填充】、【IOC-Aware回调】、【IOC初始化】等阶段入口其实也是在这个方法中。
2.8 AbstractAutowireCapableBeanFactory#createBeanInstance:实例化
方法调用链:由2.7的doCreateBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
方法注释:AbstractAutowireCapableBeanFactory这个类的中心方法:创建一个bean实例,填充bean实例,应用后处理器,等等
源码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 步骤一:再次确保类已经被加载
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 步骤二:使用Supplier创建对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 步骤三:工厂方法创建对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// 步骤四:推断构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 步骤五:实例化
return instantiateBean(beanName, mbd);
}
方法解读:
2.9 AbstractAutowireCapableBeanFactory#autowireConstructor:推断构造方法
2.10 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors:BeanDefinition后置处理
方法调用链:由2.7的doCreateBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
方法注释:将MergedBeanDefinitionPostProcessors应用于指定的bean定义,调用它们的postProcessMergedBeanDefinition方法。
源码如下:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
方法解读:Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点,即当前的MergedBeanDefinitionPostProcessors
。这里的主要难点还是,这种类型的BeanPostProcessor
的应用场景,可能才是大家比较关心的。那你们觉得,这里的主要应用场景应该是什么呢?其实,按照Spring的生命周期来说,他现在提供给你的拓展点,只能是【实例化】阶段后的生命周期了,毕竟过去已经发生的已经没办法改变。所以,我们可以在这里,干预【初始化】这个阶段,如下示例:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Object newUser = context.getBean("user");
System.out.println(newUser);
}
// 声明bean
@Component
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void myInit() {
System.out.println("这是我自己指定的初始化方法");
}
}
// 声明一个MergedBeanDefinitionPostProcessor,然后改变了User这个Bean的初始化方法
@Component
public class MyBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanName.equals("user")) {
beanDefinition.setInitMethodName("myInit");
}
}
}
PS:在Spring源码中,AutowiredAnnotationBeanPostProcessor
就是一个MergedBeanDefinitionPostProcessor
,它的postProcessMergedBeanDefinition()
中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor
对象的一个Map中(injectionMetadataCache),为依赖注入做准备。
2.11 AbstractAutowireCapableBeanFactory#populateBean:属性注入
(PS:属性注入不是我们这里需要关注的地方,但因为【实例化后】在这个方法里面,所以就只能点进来了)
方法调用链:由2.7的doCreateBean调用过来
全路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
方法注释:使用来自bean定义的属性值在给定的BeanWrapper中填充bean实例(属性填充/依赖注入)。
populateBean中关键源码如下:
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}