本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试。
记录日期:2022.1.4
大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习。
文章目录
- 框架原理 - Spring(十三)之Spring IOC 源码finishBeanFactoryInitialization()
-
- AbstractApplicationContext#finishBeanFactoryInitialization()
-
- ConversionService
- LoadTimeWeaverAware
- beanFactory.preInstantiateSingletons()【重点】
- getMergedLocalBeanDefinition(beanName)
- getMergedBeanDefinition()
- 引入:FactoryBean
- 引入:父BeanFactory
- getBean()
- dogetBean()【重点】
- getObjectForBeanInstance()
- getObjectFromFactoryBean()
- doGetObjectFromFactoryBean()
- postProcessObjectFromFactoryBean()
- markBeanAsCreated()
- isDependent()
- registerDependentBean()
- getSingleton()
- addSingleton()
- beforePrototypeCreation() 和 afterPrototypeCreation()
- createBean()【重点】
- resolveBeforeInstantiation()
- applyBeanPostProcessorsBeforeInstantiation()
- doCreateBean()【重点】
- createBeanInstance()
- determineConstructorsFromBeanPostProcessors()
- autowireConstructor()
- resolveConstructorArguments()
- createArgumentArray()
- resolveAutowiredArgument()
- resolveDependency()
- doResolveDependency()
- findAutowireCandidates()
- isAutowireCandidate()
- resolver.isAutowireCandidate()
- addCandidateEntry()
- determineAutowireCandidate()
- determinePrimaryCandidate() & determineHighestPriorityCandidate()
- storeCache()
- applyMergedBeanDefinitionPostProcessors()
- addSingletonFactory() & getEarlyBeanReference()
- populateBean()【重点】
- autowireByName()
- unsatisfiedNonSimpleProperties()
- containsBean()
- autowireByType()
- applyPropertyValues()
- initializeBean()【重点】
- invokeAwareMethods()
- applyBeanPostProcessorsBeforeInitialization()
- invokeInitMethods()
- applyBeanPostProcessorsAfterInitialization()
- registerDisposableBeanIfNecessary()
- requiresDestruction()
- registerDisposableBean() & DisposableBeanAdapter
框架原理 - Spring(十三)之Spring IOC 源码finishBeanFactoryInitialization()
AbstractApplicationContext#finishBeanFactoryInitialization()
这里会负责初始化所有的 singleton beans
。
在这个方法中,主要做了以下操作:
- 将之前解析的 BeanDefinition 进一步处理,将有父 BeanDefinition 的进行合并,获得 MergedBeanDefinition
- 尝试从缓存获取 bean 实例
- 处理特殊的 bean —— FactoryBean 的创建
- 创建 bean 实例
- 循环引用的处理
- bean 实例属性填充
- bean 实例的初始化
- BeanPostProcessor 的各种扩展应用
后面的叙述中,会使用初始化或预初始化来代表这个阶段。主要是 Spring 需要在这个阶段完成所有的 singleton beans
的实例化。
到此为止前, BeanFactory
已经创建完成,并且所有的实现了 BeanFactoryPostProcessor
接口的 Bean 都已经初始化并且其中的 postProcessBeanFactory(factory)
方法已经得到执行了。所有实现了 BeanPostProcessor
接口的 Bean 也都完成了初始化。
剩下的就是初始化其他还没被初始化的 singleton beans
了,我们知道它们是单例的,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans
。
// 初始化剩余的 singleton beans
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 【翻译注释】为此上下文初始化转换服务
// 判断是否有bdName为conversionService的beanName(实现ConversionService接口),有的话注册为格式转换器服务类
// 初始化的动作包装在 beanFactory.getBean(...) 中
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
/* 【注释翻译】 如果之前没有注册BeanFactoryPostProcessor(如PropertySourcesPlaceHolderConfigurerBean), 请注册默认嵌入值解析程序:此时,主要用于注释属性值中的解析。 */
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 【注释翻译】尽早初始化LoadTimeWeaverAware bean,以便尽早注册其转换器
// 先初始化 实现LoadTimeWeaverAware 接口的 Bean
// 一般用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入,这里不展开说
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 【注释翻译】停止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
// 【注释翻译】允许缓存所有bean定义元数据,不需要进一步更改
// 没什么别的目的,因为到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
// 肯定不希望这个时候还出现 bean 定义解析、加载、注册。
beanFactory.freezeConfiguration();
// 【注释翻译】实例化所有剩余的(非惰性初始化)单例
// 开始初始化剩下的
beanFactory.preInstantiateSingletons();
}
ConversionService
代码块如下:
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
这里是结合spring MVC使用的,类似页面传递String
类型的时间格式到后台可以格式化为Date
类型。
容器初始化完成后,默认是没有格式转换器的。
Spring 内部有个DefaultConversionService
,但是没有注册进容器,所以 Spring 找不到。
可以通过配置注入容器,然后 Spring 在这一步就会找到DefaultConversionService
并注册到conversionService
,如下:
@Bean
public ConversionService conversionService(){
DefaultConversionService ConversionService = new DefaultConversionService();
return ConversionService;
}
DefaultConversionService
会注册很多spring自带的格式转换器,包括时间,集合等…
LoadTimeWeaverAware
代码块如下:
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
这里会提前实例化LoadTimeWeaverAware类型的bean,this.getBean(bdName)
方***进行实例化bean,后面具体分析。
beanFactory.preInstantiateSingletons()【重点】
DefaultListableBeanFactory.preInstantiateSingletons()
方法实现如下:
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
/* 【注释翻译】 迭代副本以允许init方法注册新的bean定义。 虽然这可能不是常规工厂引导的一部分,但它在其他方面工作正常。 */
// this.beanDefinitionNames就是之前注册bean的时候添加的beanName集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 【注释翻译】触发所有非惰性单例bean的初始化......
// 触发所有的非懒加载的 singleton beans 的初始化操作
for (String beanName : beanNames) {
// 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent,这个一般用的不多
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懒加载的 singletons。(如果配置了 'abstract = true',那是不需要初始化的)
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 处理 FactoryBean
if (isFactoryBean(beanName)) {
// FACTORY_BEAN_PREFIX = "&"
// FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号。再调用 getBean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 判断当前 FactoryBean 是否是 SmartFactoryBean 的实现
// 即 判断这个FactoryBean是否希望急切的初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 如果希望急切的初始化,则通过beanName获取bean实例
getBean(beanName);
}
}
}
else {
// 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
getBean(beanName);
}
}
}
// 【翻译注释】触发所有适用bean的初始化后回调......
// 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调
for (String beanName : beanNames) {
// 拿到beanName对应的bean实例
Object singletonInstance = getSingleton(beanName);
// 判断singletonInstance是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
getMergedLocalBeanDefinition(beanName)
获取 beanName
对应的 MergedBeanDefinition
。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 【翻译注释】首先快速检查并发映射,以最小化锁定。
// 1. 检查beanName对应的MergedBeanDefinition是否存在于缓存中
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
// 2. 如果存在于缓存中则直接返回
return mbd;
}
/* 3. 如果不存在于缓存中 3.1 getBeanDefinition(beanName): 获取beanName对应的BeanDefinition,从beanDefinitionMap缓存中获取 3.2 getMergedBeanDefinition(): 根据beanName和对应的BeanDefinition,获取MergedBeanDefinition */
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
getMergedBeanDefinition()
根据 beanName
和 beanName
对应的 BeanDefinition
,获取 MergedBeanDefinition
。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 1. 加锁再进行操作
synchronized (this.mergedBeanDefinitions) {
// 用于存储bd的MergedBeanDefinition,也就是该方法的结果
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
// 2. 检查beanName对应的MergedBeanDefinition是否存在于缓存中,这里差不多是一个双重校验的意思
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 3. 如果beanName对应的MergedBeanDefinition不存在于缓存中
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
/* 4. 如果bd的parentName为空,代表bean没有父定义,无需与父定义进行合并操作, 也就是bean的MergedBeanDefinition就是bean本身(可能需要转成RootBeanDefinition) */
if (bd instanceof RootBeanDefinition) {
// 4.1 如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// 4.2 否则,将bd作为参数,构建一个RootBeanDefinition
// 正常使用下,BeanDefinition在被加载后是GenericBeanDefinition或ScannedGenericBeanDefinition
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
// 5. 否则,bd存在父定义,需要与父定义合并
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
// 5.1 如果父定义的beanName与该bean的beanName不同
if (!beanName.equals(parentBeanName)) {
// 5.2 获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,也就是bd的爷爷定义...)
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory
// 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// // 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
// 5.6 如果父BeanFactory不是ConfigurableBeanFactory,则抛异常
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
mbd = new RootBeanDefinition(pbd);
// 5.8 使用bd覆盖父定义
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// 6.如果没有配置scope,则设置成默认的singleton
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton,则将mdb的scope设置为containingBd的scope
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// 8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
// 9.返回MergedBeanDefinition
return mbd;
}
}
其中transformedBeanName
方法,主要是将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
// 如果beanName不带有 "&" 前缀,则直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 如果beanName带有 "&" 前缀,则去掉
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 将别名解析成真正的beanName
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
引入:FactoryBean
一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。而 FactoryBean
是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean
接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject()
方法。
注:很多中间件都利用 FactoryBean 来进行扩展。
举例说明:
public class AppleFactoryBean implements FactoryBean<Apple> {
@Override
public Apple getObject() throws Exception {
Apple apple = new Apple();
apple.setName("bigApple");
return apple;
}
@Override
public Class<?> getObjectType() {
return Apple.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
为了区分 FactoryBean
和 FactoryBean 创建的 bean 实例
,Spring 使用了 &
前缀。假设我们的 beanName 为 apple,则 getBean("apple")
获得的是 AppleFactoryBean
通过 getObject()
方法创建的 bean 实例;而 getBean("&apple")
获得的是 AppleFactoryBean
本身。
引入:父BeanFactory
我们能看到getMergedBeanDefinition(beanName)
方法是用来获取父定义的MergedBeanDefinition。
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
return getMergedLocalBeanDefinition(beanName);
}
父BeanFactory,意思是在 Spring 中可能存在多个 BeanFactory
,多个 BeanFactory
可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory
和 Spring 的 BeanFactory
,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory
是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition
,因而,如果在当前 BeanFactory
中找不到,而又存在父工厂,则会去父工厂中查找。
getBean()
接下来重点讲一下getBean()
这个方法了。
这个方法我们经常用来从 BeanFactory 中获取一个 Bean,而初始化的过程也封装到了这个方法里。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
而实际上是调用了doGetBean()
方法,下面来重点看一下它的代码.
spring对于实际操作的方法都喜欢加一个do前缀。
dogetBean()【重点】
dogetBean()
方法的实现如下:
// 我们在剖析初始化 Bean 的过程,但是 getBean 方法我们经常是用来从容器中获取 Bean 用的,注意切换思路,
// 已经初始化过了就从容器中直接返回,否则就先初始化再返回
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/* 1. 获取一个 “正统的” beanName, 处理两种情况: 一个是前面说的 FactoryBean(前面带 ‘&’); 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的。 */
String beanName = transformedBeanName(name);
// 注意跟着它,它就是最终返回值
Object beanInstance;
// 【翻译注释】急切地检查手动注册的单例缓存
// 2. 检查下是不是已经创建过了,即尝试从缓存中获取beanName对应的实例
Object sharedInstance = getSingleton(beanName);
// 这里说下 args,虽然看上去一点不重要。前面我们一路进来的时候都是 getBean(beanName),
// 所以 args 其实是 null 的,但是如果 args 不为空的时候,那么意味着调用方不是希望获取 Bean,而是创建 Bean
if (sharedInstance != null && args == null) {
// 3. 如果beanName的实例存在于缓存中
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/* 3.1 返回beanName对应的实例对象 下面这个方法: 如果是普通 Bean 的话,直接返回 sharedInstance, 如果是 FactoryBean 的话,返回它创建的那个实例对象 */
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 【翻译注释】如果我们已经在创建这个bean实例,则失败:我们应该在一个循环引用中
/* 4. scope为prototype的循环依赖校验: 如果beanName已经正在创建Bean实例中, 而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候, 就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖 */
if (isPrototypeCurrentlyInCreation(beanName)) {
// 当前线程已经创建过了此 beanName 的 prototype 类型的 bean,那么抛异常
throw new BeanCurrentlyInCreationException(beanName);
}
// 【翻译注释】检查此工厂中是否存在bean定义
// 5. 检查一下这个 BeanDefinition 在容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5.1 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 【翻译注释】未找到 -> 检查父项。
// 5.2 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 5.3 尝试在parentBeanFactory中获取bean对象实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 【翻译注释】委托给具有显式参数的父级。
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 【翻译注释】无参数 -> 委托给标准getBean方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 做个记录,标识bd正在实例化
// 6. 如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
markBeanAsCreated(beanName);
}
/* 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean; 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。 */
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 根据beanName获取bean
// 7. 根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 7.1 检查MergedBeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);
// 【翻译注释】保证当前bean所依赖的bean的初始化
// 先初始化依赖的所有 Bean,这个很好理解。但是注意,这里的依赖指的是 depends-on 中定义的依赖
// @DependsOn注解控制bean的加载顺序
// 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 8.1 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 8.3 如果是循环依赖则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 8.4 将dep和beanName的依赖关系注册到缓存中
registerDependentBean(dep, beanName);
try {
// 8.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 【翻译注释】创建bean实例
// 9.针对不同的scope进行bean的创建
// 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 9.1.1 创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
/* 【翻译注释】 显式地从单例缓存中删除实例: 创建过程可能会急切地将实例放在那里,以允许循环引用解析。 还要删除接收到对bean的临时引用的任何bean */
destroySingleton(beanName);
throw ex;
}
});
// 9.1.2 返回beanName对应的实例对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 9.2 scope为prototype的bean创建
else if (mbd.isPrototype()) {
// 【翻译注释】这是一个原型 -> 创建一个新实例。
Object prototypeInstance = null;
try {
// 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
// 9.2.2 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
// 9.2.4 返回beanName对应的实例对象
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 9.3 其他scope的bean创建,可能是request之类的
else {
// 9.3.1 根据scopeName,从缓存拿到scope实例
String scopeName = mbd.getScope();
// 如果没有配置scope,则抛异常
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, () -> {
// 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 9.3.4 创建bean实例
return createBean(beanName, mbd, args);
}
finally {
// 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
});
// 9.3.6 返回beanName对应的实例对象
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
// 10. 最后,检查一下类型,不对的话就抛异常,对的话就返回
return adaptBeanInstance(name, beanInstance, requiredType);
}
getObjectForBeanInstance()
在上述dogetBean()
代码块 3.1
中。
返回beanName对应的实例对象。
- 如果是
普通 Bean
的话,直接返回sharedInstance
。 - 如果是
FactoryBean
的话,返回它创建的那个实例对象。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 1.如果name以“&”为前缀
// 这里说明要返回的是 FactoryBean
if (BeanFactoryUtils.isFactoryDereference(name)) {
// 1.1 如果是个空bean
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 1.2 如果beanInstance不是FactoryBean,则抛异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 2. 如果beanInstance不是FactoryBean(也就是普通bean),则直接返回beanInstance
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 3.走到这边,代表beanInstance是FactoryBean,但name不带有“&”前缀,表示想要获取的是FactoryBean创建的对象实例
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 4.如果mbd为空,则尝试从factoryBeanObjectCache缓存中获取该FactoryBean创建的对象实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 5.只有beanInstance是FactoryBean才能走到这边,因此直接强转
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
// 6.mbd为空,但是该bean的BeanDefinition在缓存中存在,则获取该bean的MergedBeanDefinitio
mbd = getMergedLocalBeanDefinition(beanName);
}
7.mbd是否是合成的(这个字段比较复杂,mbd正常情况都不是合成的,也就是false,有兴趣的可以自己查阅资料看看)
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 8.从FactoryBean获取对象实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
// 9.返回对象实例
return object;
}
getObjectFromFactoryBean()
在上述getObjectForBeanInstance()
代码块 8
中。
从 FactoryBean
获取对象实例。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 1.如果是单例,并且已经存在于单例对象缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 2.从FactoryBean创建的单例对象的缓存中获取该bean实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 3.调用FactoryBean的getObject方法获取对象实例
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 4.如果该beanName已经在缓存中存在,则将object替换成缓存中的
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 5. 如果需要执行这个bean的后置处理
if (shouldPostProcess) {
// 暂时返回未经处理的单例bean
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 5.1 检测是否是正在创建的单例bean,添加到singletonsCurrentlyInCreation中
beforeSingletonCreation(beanName);
try {
// 5.2 对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
// 默认实现只是按原样返回给定对象,子类可以重写该方法
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 5.3 检测是否是正在创建的单例bean,,从singletonsCurrentlyInCreation移除
afterSingletonCreation(beanName);
}
}
// 6. 将beanName和object放到factoryBeanObjectCache缓存中
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
// 7.返回object对象实例
return object;
}
}
else {
// 8.调用FactoryBean的getObject方法获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 9.对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
// 10.返回object对象实例
return object;
}
}
doGetObjectFromFactoryBean()
在上述getObjectFromFactoryBean()
代码块 3
、8
中。
调用 FactoryBean
的getObject
方法获取对象实例。
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
// 1.调用FactoryBean的getObject方法获取bean对象实例
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
// 1.1 带有权限验证的
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 1.2 不带有权限验证的
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
// 2. getObject返回的是空值,并且该FactoryBean正在初始化中,则直接抛异常,不接受一个尚未完全初始化的FactoryBean的getObject返回的空值
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
// 3. 返回创建好的bean对象实例
return object;
}
很简单的方法,就是直接调用 FactoryBean 的 getObject 方法来获取到对象实例。
postProcessObjectFromFactoryBean()
在上述getObjectFromFactoryBean()
代码块 5.2
、9
中。
/** * Post-process the given object that has been obtained from the FactoryBean. * The resulting object will get exposed for bean references. * <p>The default implementation simply returns the given object as-is. * Subclasses may override this, for example, to apply post-processors. * @param object the object obtained from the FactoryBean. * @param beanName the name of the bean * @return the object to expose * @throws org.springframework.beans.BeansException if any post-processing failed */
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
默认是空实现的处理方法,但是空方法有什么好看的呢,当然看他的实现类啦。
这边走的是 AbstractAutowireCapableBeanFactory
里的方法。通过前面的介绍,我们知道创建的 BeanFactory 为 DefaultListableBeanFactory
,而 DefaultListableBeanFactory
继承了 AbstractAutowireCapableBeanFactory
,因此这边会走 AbstractAutowireCapableBeanFactory
的重写方法。
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2.在bean初始化后,调用postProcessAfterInitialization方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
// 3.如果返回null,则不会调用后续的BeanPostProcessors
return result;
}
result = current;
}
return result;
}
markBeanAsCreated()
让我们回看dogetBean()
代码块的 6
中。
这边会将 beanName 对应的 MergedBeanDefinition
移除,然后在之后的代码重新获取,主要是为了使用最新的 MergedBeanDefinition
来进行创建操作。
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
// 双重校验
// 1.如果alreadyCreated缓存中不包含beanName
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 2.将beanName的MergedBeanDefinition从mergedBeanDefinitions缓存中移除,
// 在之后重新获取MergedBeanDefinition,避免BeanDefinition在创建过程中发生变化
clearMergedBeanDefinition(beanName);
// 3.将beanName添加到alreadyCreated缓存中,代表该beanName的bean实例已经创建(或即将创建)
this.alreadyCreated.add(beanName);
}
}
}
}
isDependent()
让我们回看dogetBean()
代码块的 8.2
中。
这边引入了一个缓存 dependentBeanMap
:beanName
-> 所有依赖 beanName 对应的 bean 的 beanName 集合
。内容比较简单,就是检查依赖 beanName 的集合中是否包含 dependentBeanName
,隔层依赖也算。例如:A 依赖了 B,B 依赖了 C,则 A 也算依赖了 C。
protected boolean isDependent(String beanName, String dependentBeanName) {
synchronized (this.dependentBeanMap) {
return isDependent(beanName, dependentBeanName, null);
}
}
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
// 已经检查过的直接跳过
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 1. 将别名解析为真正的名称
String canonicalName = canonicalName(beanName);
// 2. 拿到依赖canonicalName的beanName集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
// 3. 如果dependentBeans为空,则两者必然还未确定依赖关系,返回false
if (dependentBeans == null) {
return false;
}
// 4. 如果dependentBeans包含dependentBeanName,则表示两者已确定依赖关系,返回true
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
// 5. 循环检查,即检查依赖canonicalName的所有beanName是否存在被dependentBeanName依赖的(即隔层依赖)
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
// 6.已经检查过的添加到alreadySeen,避免重复检查
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
registerDependentBean()
让我们回看dogetBean()
代码块的 8.4
中。
将``dep和
beanName` 的依赖关系注册到缓存中。
这边又引入了一个跟 dependentBeanMap
类似的缓存,dependenciesForBeanMap
:beanName
-> beanName 对应的 bean 依赖的所有 bean 的 beanName 集合
。
这两个缓存很容易搞混,举个简单例子:例如 B 依赖了 A,则 dependentBeanMap 缓存中应该存放一对映射:其中 key 为 A,value 为含有 B 的 Set;而 dependenciesForBeanMap 缓存中也应该存放一对映射:其中 key 为:B,value 为含有 A 的 Set。
public void registerDependentBean(String beanName, String dependentBeanName) {
// 1. 解析别名
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
// 2. 拿到依赖canonicalName的beanName集合,如果不存在则创建集合
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
// 3. 如果dependentBeans包含dependentBeanName,则表示依赖关系已经存在,直接返回
// 如果不包含,则添加成功
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
// 同上,在dependenciesForBeanMap中也注册一遍
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
getSingleton()
让我们回看dogetBean()
代码块的 9.1
中。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 1. 加锁,避免重复创建单例对象
synchronized (this.singletonObjects) {
// 2. 首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 3. beanName对应的bean实例不存在于缓存中,则进行Bean的创建
if (this.singletonsCurrentlyInDestruction) {
// 4.当bean工厂的单例处于destruction状态时,不允许进行单例bean创建,抛出异常
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 5.创建单例前的操作
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// suppressedExceptions用于记录异常相关信息
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 6.执行singletonFactory的getObject方法获取bean实例
singletonObject = singletonFactory.getObject();
// 标记为新的单例对象
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 7.创建单例后的操作
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 8.如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)
addSingleton(beanName, singletonObject);
}
}
// 9.返回创建出来的单例对象
return singletonObject;
}
}
其中beforeSingletonCreation
和afterSingletonCreation
也是一个前后置操作,是相互对应的,简单看一下它们两者的实现:
inCreationCheckExclusions
是要在创建检查排除掉的 beanName
集合,正常为空,可以不管。这边主要是引入了 singletonsCurrentlyInCreation
缓存:当前正在创建的 bean 的 beanName
集合。在 beforeSingletonCreation
方法中,通过添加 beanName 到该缓存,可以预防出现构造器循环依赖的情况。
protected void beforeSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName加入到正在创建bean的缓存中(Set),如果beanName已经存在于该缓存,会返回false抛出异常(这种情况出现在构造器的循环依赖)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName从正在创建bean的缓存中(Set)移除,如果beanName不存在于该缓存,会返回false抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
getSingleton
方法是解决循环引用的核心代码。解决逻辑的第一句话:“我们先用构造函数创建一个 “不完整” 的 bean 实例”,从这句话可以看出,构造器循环依赖是无法解决的,因为当构造器出现循环依赖,我们连 “不完整” 的 bean 实例都构建不出来。Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖。
addSingleton()
让我们来看getSingleton()
代码块的 8
中。
如果是新的单例对象,将beanName和对应的bean实例添加到缓存中。
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 1.添加到单例对象缓存
this.singletonObjects.put(beanName, singletonObject);
// 2.将单例工厂缓存移除(已经不需要)
this.singletonFactories.remove(beanName);
// 3.将早期单例对象缓存移除(已经不需要)
this.earlySingletonObjects.remove(beanName);
// 4.添加到已经注册的单例对象缓存
this.registeredSingletons.add(beanName);
}
}
beforePrototypeCreation() 和 afterPrototypeCreation()
让我们来看dogetBean()
代码块的 9.2.1
和 9.3.1
中。
该方法和getSingleton()
中的两个方法类似。主要是在进行 bean 实例的创建前,将 beanName 添加到 prototypesCurrentlyInCreation
缓存;bean 实例创建后,将 beanName 从 prototypesCurrentlyInCreation
缓存中移除。这边 prototypesCurrentlyInCreation
存放的类型为 Object
,在只有一个 beanName
的时候,直接存该 beanName
,也就是 String 类型;当有多个 beanName
时,转成 Set 来存放。
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
// 1. 拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2. 如果为空,则将ThreadLocal设置成当前的beanName
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
// 3. 如果不为空,并且是String类型,则代表目前只有一个beanName,将之前和当前的一起封装成Set<String>,设置到ThreadLocal中
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
// 4. 如果不为空,并且不是String,则必然是Set<String>类型,将当前的beanName加到Set中去
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
// 1. 拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2. 如果是String类型,则代表目前只有一个beanName,则直接移除
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
}
// 3. 如果是Set类型,则从Set从移除beanName
else if (curVal instanceof Set) {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}
createBean()【重点】
AbstractBeanFactory#createBean()
是一个抽象模板方法。
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
具体实现是由AbstractAutowireCapableBeanFactory#createBean()
来完成的:
@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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 1. 解析beanName对应的Bean的类型,例如:com.test.service.impl.UserServiceImpl
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
/* 如果resolvedClass存在,并且mdb的beanClass类型不是Class, 并且mdb的beanClass不为空(则代表beanClass存的是Class的name), 则使用mdb深拷贝一个新的RootBeanDefinition副本, 并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性, 该拷贝副本取代mdb用于后续的操作。 */
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2.验证及准备覆盖的方法(对override属性进行标记及验证)
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 5.创建Bean实例(真正创建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 6.返回创建的Bean实例
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);
}
}
resolveBeforeInstantiation()
我们来看 createBean()
代码块的 3
中。
@Nullable
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.
// 1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 2.解析beanName对应的Bean实例的类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor)
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 4.如果返回的bean不为空,会跳过Spring默认的实例化过程,
// 所以只能在这里调用BeanPostProcessor实现类的postProcessAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// 5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation()
实例化前 BeanPostProcessor
的调用。
在实例化之前执行 InstantiationAwareBeanPostProcessor
的 postProcessBeforeInstantiation
方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 1. 遍历所有实现InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 2. 执行postProcessBeforeInstantiation方法,在Bean实例化前操作
// 该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的“正规的流程”,达到“短路”的效果。
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
// 3. 如果result不为空,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程
return result;
}
}
return null;
}
其中调用了getBeanPostProcessorCache()
,它其实就是一个用来区分实现不同接口的的缓存集合,因为此时的 BeanPostProcessor
都已经注册完成,为了防止多次遍历,直接提供缓存会更加高效。
// 返回预过滤后处理器的内部缓存,必要时重新构建
// 主要目的是为了减少遍历,快速获取对应实现类的BeanPostProcessor
BeanPostProcessorCache getBeanPostProcessorCache() {
// 1. 获取当前容器中的beanPostProcessorCache
BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
if (bpCache == null) {
// 2. 如果为空则初始化
bpCache = new BeanPostProcessorCache();
// 3. 遍历之前注册完成的所有beanPostProcessors
for (BeanPostProcessor bp : this.beanPostProcessors) {
// 3.1 如果bp实现了InstantiationAwareBeanPostProcessor接口
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 3.1.1 添加到instantiationAware集合中
bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
// 3.1.2 如果bp还实现了SmartInstantiationAwareBeanPostProcessor接口
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 3.1.3 添加到smartInstantiationAware集合中
bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
}
}
// 3.2 如果bp实现了DestructionAwareBeanPostProcessor接口
if (bp instanceof DestructionAwareBeanPostProcessor) {
bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
}
// 3.3 如果bp实现了MergedBeanDefinitionPostProcessor接口
if (bp instanceof MergedBeanDefinitionPostProcessor) {
bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
}
}
// 初始化缓存完成
this.beanPostProcessorCache = bpCache;
}
return bpCache;
}
static class BeanPostProcessorCache {
final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();
final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();
final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();
final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
}
doCreateBean()【重点】
我们来看 createBean()
代码块的 5
中。
这才是Spring真正创建bean实例的方法,代码前后关联紧密,需要多理解几遍。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 1. 新建Bean包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 2. 如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 3. 根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4. 拿到创建好的Bean实例
Object bean = instanceWrapper.getWrappedInstance();
// 5. 拿到Bean实例的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 6. 应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
// Autowired注解正是通过此方法实现注入类型的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// addSingletonFactory() -> 8.提前曝光beanName的ObjectFactory,用于解决循环引用
// getEarlyBeanReference() -> 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance. 初始化bean实例
Object exposedObject = bean;
try {
// 9. 对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
populateBean(beanName, mbd, instanceWrapper);
// 10.对bean进行初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 11.如果允许提前曝光实例,则进行循环依赖检查
Object earlySingletonReference = getSingleton(beanName, false);
// 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用
exposedObject = earlySingletonReference;
}
/* 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例 && 当前bean有被其他bean依赖 */
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 11.4 拿到依赖当前bean的所有bean的beanName数组
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 11.6 移除失败的添加到 actualDependentBeans
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 13.完成创建并返回
return exposedObject;
}
createBeanInstance()
我们来看 doCreateBean()
代码块的 3
中。
创建实例的方法通常有以下几种:
- 工厂方法
- 构造函数自动装配(通常指带有参数的构造函数)
- 简单实例化(默认的构造函数)
- Supplier创建(本质上是 lambda表达式<函数式接口>)
其中工厂方法现在基本不使用了,不再解析;简单实例化过程比较简单,也不解析;Supplier创建不太常见吧,想了解的话稍微看一下Spring中 Supplier创建bean
本段落只对构造函数自动装配进行解析。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析bean的类型信息
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// beanClass不为空 && beanClass不是公开类(不是public修饰) && 该bean不允许访问非公共构造函数和方法,则抛异常
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());
}
// 1. 从 BeanDefinition 信息中获取supplier接口方法,如果存在直接使用supplier函数式接口完成bean的初始化
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 2. 如果存在工厂方法则使用工厂方法实例化bean对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// resolved 标识构造函数或工厂方法是否已经解析过
boolean resolved = false;
// autowireNecessary 标识是否需要自动注入(即是否需要解析构造函数参数)
boolean autowireNecessary = false;
if (args == null) {
// 3. 加锁
synchronized (mbd.constructorArgumentLock) {
// 3.1 如果resolvedConstructorOrFactoryMethod缓存不为空,则将resolved标记为已解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// 3.2 根据constructorArgumentsResolved判断是否需要自动注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 4. 如果已经解析过,则使用resolvedConstructorOrFactoryMethod缓存里解析好的构造函数方法
if (autowireNecessary) {
// 4.1 需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 4.2 否则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 5. 应用后置处理器SmartInstantiationAwareBeanPostProcessor,拿到bean的候选构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如果推断出来了构造方法,则需要给构造方法赋值,也就是给构造方法参数赋值,也就是构造方法注入
// 如果没有推断出来构造方法,但是autowiremode为AUTOWIRE_CONSTRUCTOR,则也可能需要给构造方法赋值,因为不确定是用无参的还是有参的构造方法
// 如果通过BeanDefinition指定了构造方法参数值,那肯定就是要进行构造方法注入了
// 如果调用getBean的时候传入了构造方法参数值,那肯定就是要进行构造方法注入了
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
/* // 6. 如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mbd定义了构造函数的参数值 || args不为空,则执行构造函数自动注入 */
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 7. 没有特殊处理,则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
determineConstructorsFromBeanPostProcessors()
我们来看 createBeanInstance()
代码块的 5
中。
调用 SmartInstantiationAwareBeanPostProcessor
的 determineCandidateConstructors
方法,该方法可以返回要用于 beanClass
的候选构造函数。使用 @Autowire
注解修饰构造函数,则该构造函数在这边会被 AutowiredAnnotationBeanPostProcessor
找到。
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
/* 调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法, 该方法可以返回要用于beanClass的候选构造函数 例如:使用@Autowire注解修饰构造函数,则该构造函数在这边会被AutowiredAnnotationBeanPostProcessor找到 */
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
// 如果ctors不为空,则不再继续执行其他的SmartInstantiationAwareBeanPostProcessor
return ctors;
}
}
}
return null;
}
autowireConstructor()
参考博客文章:Spring推断构造方法(中)_
我们来看 createBeanInstance()
代码块的 6
中。
推断构造方法的代码逻辑顺序列举:
- 初步确定构造方法和参数
使用constructorToUse变量存将要使用的构造方法,argsToUse变量存需要使用的构造方法参数值,ArgumentsHolder是对构造方法参数值的封装。首先判断getBean()方法调用时有没有指定构造方法参数,如果指定了,则优先使用指定的值作为构造方法的参数值;如果没有指定,则判断BeanDefinition中是否缓存了构造方法参数值。
- 推断构造方法和方法参数:如果缓存中没有构造方法,或者没有得到可用的构造方法参数,则需要自行去推断获取。
- 推断使用默认无参构造方法
- 记录构造方法的最小参数个数
- 对构造方法进行排序
- 遍历构造方法进行筛选
- 寻找构造方法参数
- 寻找最佳的构造方法
- 生成实例
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
// ConstructorResolver 构造方法
public ConstructorResolver(AbstractAutowireCapableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
this.logger = beanFactory.getLogger();
}
// ConstructorResolver 127
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 定义bean包装类
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 最终用于实例化的构造函数
Constructor<?> constructorToUse = null;
// 最终用于实例化的参数Holder
ArgumentsHolder argsHolderToUse = null;
// 最终用于实例化的构造函数参数
Object[] argsToUse = null;
// 1.解析出要用于实例化的构造函数参数
if (explicitArgs != null) {
// 1.1 如果explicitArgs不为空,则构造函数的参数直接使用explicitArgs
// 如果通过getBean方法调用时,显示指定了参数,则explicitArgs就不为null
argsToUse = explicitArgs;
}
else {
// 1.2 尝试从缓存中获取已经解析过的构造函数参数
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 1.2.1 拿到缓存中已解析的构造函数或工厂方法
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 1.2.2 如果constructorToUse不为空 && mbd标记了构造函数参数已解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 1.2.3 从缓存中获取已解析的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
/* 1.2.4 如果resolvedConstructorArguments为空,则从缓存中获取准备用于解析的构造函数参数, constructorArgumentsResolved为true时,resolvedConstructorArguments和 preparedConstructorArguments必然有一个缓存了构造函数的参数 */
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 1.2.5 如果argsToResolve不为空,则对构造函数参数进行解析,
// 如给定方法的构造函数 A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
// 2.如果没有确定要使用的构造方法,或者确定了构造方法但是所要传入的参数值没有确定
/* 此时说明只有两种情况为null: 1、只有一个默认的无参构造方法; 2、有多个有参构造方法。 */
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// 2.1 如果没有指定构造方法,那就获取beanClass中的所有构造方法所谓候选者
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 2.2 如果只有一个候选构造方法,并且没有指定所要使用的构造方法参数值,并且该构造方法是无参的,那就直接用这个无参构造方法进行实例化了
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 2.3 将构造方法以及参数(空数组)进行缓存,防止后面不必要的构造推断
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// Need to resolve the constructor.
// 2.1 检查是否需要进行构造注入自动装配:候选的构造方法不为空 || 指定注入方式为构造注入时
/* 候选的构造方法不为空包含两种情况: 1、有加了@Autowired的构造方法 2、只有一个多参的构造方法,对于这两种情况,都需要进行构造注入 */
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
// 3. 确定要选择的构造方法的参数个数的最小值,后续判断候选构造方法的参数个数如果小于minNrOfArgs,则直接pass掉
int minNrOfArgs;
if (explicitArgs != null) {
// 3.1 如果直接传了构造方法参数值,那么所用的构造方法的参数个数肯定不能少于传了的构造方法参数值长度
minNrOfArgs = explicitArgs.length;
}
else {
// 3.2 获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值)
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 3.3 创建ConstructorArgumentValues对象resolvedValues,用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 3.4 解析mbd的构造函数的参数,并返回参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
// 注:这边解析mbd中的构造函数参数值,主要是处理我们通过xml方式定义的构造函数注入的参数,
// 但是如果我们是通过@Autowire注解直接修饰构造函数,则mbd是没有这些参数值的
}
// 4. 对候选构造方法进行排序,public的方法排在最前面,都是public的情况下参数个数越多越靠前
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
// 5. 遍历每个构造方法,进行筛选
for (Constructor<?> candidate : candidates) {
// 参数个数
int parameterCount = candidate.getParameterCount();
// 5.1 本次遍历时,之前已经选出来了所要用的构造方法和入参对象,并且入参对象个数比当前遍历到的这个构造方法的参数个数多,则不用再遍历,退出循环
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 5.2 如果参数个数小于所要求的参数个数,则遍历下一个,这里考虑的是同时存在public和非public的构造方法
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
// 没有通过getBean()指定构造方法参数值
// 5.3 resolvedValues不为空
if (resolvedValues != null) {
// 存在参数则根据参数值来匹配参数类型
try {
// 5.3.1 获取当前遍历的构造函数的参数名称
// 5.3.1.1 如果在构造方法上使用了@ConstructorProperties,那么就直接取定义的值作为构造方法的参数名
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
// 获取构造方法参数名
if (paramNames == null) {
// 5.3.1.2 获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 5.3.1.3 使用参数名称解析器获取当前遍历的构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 5.3.2 创建一个参数数组以调用构造函数或工厂方法,
// 主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// 5.3.3 当前正在遍历的构造方法找不到可用的入参对象,记录一下
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
// 5.4 resolvedValues为空,则explicitArgs不为空,即给出了显式参数
// 5.4.1 如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数
if (parameterCount != explicitArgs.length) {
continue;
}
// 5.4.2 使用显式给出的参数构造ArgumentsHolder
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 5.5 根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),
// 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) :
argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 5.6 类型差异权重值越小,则说明构造函数越匹配,则选择此构造函数
if (typeDiffWeight < minTypeDiffWeight) {
// 将要使用的参数都替换成差异权重值更小的
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
// 如果出现权重值更小的候选者,则将ambiguousConstructors清空,允许之前存在权重值相同的候选者
ambiguousConstructors = null;
}
// 5.7 如果存在两个候选者的权重值相同,并且是当前遍历过权重值最小的
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 5.8 将这两个候选者都添加到ambiguousConstructors
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
// 6. 如果没有可用的构造方法,就取记录的最后一个异常并抛出
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
// 7. 如果有可用的构造方法,但是有多个
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
// 8. 如果没有通过getBean方法传入参数,并且找到了构造方法以及要用的入参对象则缓存
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
resolveConstructorArguments()
我们来看 autowireConstructor()
代码块的 3.4
中。
解析 mbd 的构造函数的参数,并返回参数个数。
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 1.构建bean定义值解析器
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// 2.minNrOfArgs初始化为indexedArgumentValues和genericArgumentValues的的参数个数总和
int minNrOfArgs = cargs.getArgumentCount();
// 3.遍历解析带index的参数值
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
// index从0开始,不允许小于0
throw new BeanCreationException(mbd.getResourceDescription(),
beanName,
"Invalid constructor argument index: " + index);
}
// 3.1 如果index大于minNrOfArgs,则修改minNrOfArgs
if (index > minNrOfArgs) {
// index是从0开始,并且是有序递增的,所以当有参数的index=5时,代表该方法至少有6个参数
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 3.2 解析参数值
if (valueHolder.isConverted()) {
// 3.2.1 如果参数值已经转换过,则直接将index和valueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, valueHolder);
} else {
// 3.2.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 3.2.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue,
valueHolder.getType(),
valueHolder.getName());
// 3.2.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 3.2.5 将index和新的ValueHolder添加到resolvedValues的indexedArgumentValues属性
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}
// 4.遍历解析通用参数值(不带index)
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
if (valueHolder.isConverted()) {
// 4.1 如果参数值已经转换过,则直接将valueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(valueHolder);
} else {
// 4.2 如果值还未转换过,则先进行转换
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument",
valueHolder.getValue());
// 4.3 使用转换后的resolvedValue构建新的ValueHolder
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue,
valueHolder.getType(),
valueHolder.getName());
// 4.4 将转换前的valueHolder保存到新的ValueHolder的source属性
resolvedValueHolder.setSource(valueHolder);
// 4.5 将新的ValueHolder添加到resolvedValues的genericArgumentValues属性
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
// 5.返回构造函数参数的个数
return minNrOfArgs;
}
createArgumentArray()
我们来看 autowireConstructor()
代码块的 5.3.2
中。
创建一个参数数组以调用构造函数或工厂方法,主要是通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他 bean,则会解析依赖的 bean)。
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
// 获取类型转换器
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 新建一个ArgumentsHolder来存放匹配到的参数
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 1. 遍历参数类型数组
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
// 拿到当前遍历的参数类型
Class<?> paramType = paramTypes[paramIndex];
// 拿到当前遍历的参数名
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// 【翻译注释】尝试查找匹配的构造函数参数值,无论是索引的还是泛型的
// 2. 查找当前遍历的参数,是否在mdb对应的bean的构造函数参数中存在index、类型和名称匹配的
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
// 3.如果我们找不到直接匹配并且不应该自动装配,那么让我们尝试下一个通用的无类型参数值作为降级方法:它可以在类型转换后匹配(例如,String - > int)。
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// 4.valueHolder不为空,存在匹配的参数
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
// 将valueHolder添加到usedValueHolders
usedValueHolders.add(valueHolder);
// 原始属性值
Object originalValue = valueHolder.getValue();
// 转换后的属性值
Object convertedValue;
if (valueHolder.isConverted()) {
// 4.1 如果valueHolder已经转换过
// 4.1.1 则直接获取转换后的值
convertedValue = valueHolder.getConvertedValue();
// 4.1.2 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = convertedValue;
}
else {
// 4.2 如果valueHolder还未转换过
// 4.2.1 获取对应构造参数或工厂方法对应索引的方法参数
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
// 4.2.2 将方法对应索引的原始值转换为paramType类型的值
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
// 如果类型转换失败,抛出TypeMismatchException
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
// 4.2.3 拿到原始参数值
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
// 4.2.4
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
// 4.2.5 args标记为需要解析
args.resolveNecessary = true;
// 4.2.6 将convertedValue作为args在paramIndex位置的预备参数
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
}
else {
// 5.valueHolder为空,不存在匹配的参数
// 5.1 将方法(此处为构造函数)和参数索引封装成MethodParameter
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
// 5.2 找不到明确的匹配,并且不是自动装配,则抛出异常
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
// 5.3 如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象
// 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
// 5.4 将通过自动装配解析出来的参数赋值给args
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
}
catch (BeansException ex) {
// 5.5 如果自动装配解析失败,则会抛出异常
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
// 6.如果依赖了其他的bean,则注册依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
resolveAutowiredArgument()
我们来看 createArgumentArray()
代码块的 5.3
中。
如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的 bean 实例对象。
@Nullable
protected Object resolveAutowiredArgument(
MethodParameter param,
String beanName,
@Nullable Set<String> autowiredBeanNames,
TypeConverter typeConverter,
boolean fallback) {
Class<?> paramType = param.getParameterType();
// 1.如果参数类型为InjectionPoint(Spring注入点类)
if (InjectionPoint.class.isAssignableFrom(paramType)) {
// 1.1 拿到当前的InjectionPoint(存储了当前正在解析依赖的方法参数信息,DependencyDescriptor)
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
// 1.2 当前injectionPoint为空,则抛出异常:目前没有可用的InjectionPoint
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
// 1.3 返回当前的InjectionPoint
return injectionPoint;
}
try {
// 2.解析指定依赖,DependencyDescriptor:将MethodParameter的方法参数索引信息封装成DependencyDescriptor
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
catch (NoUniqueBeanDefinitionException ex) {
throw ex;
}
catch (NoSuchBeanDefinitionException ex) {
if (fallback) {
// 单个构造函数或工厂方法 -> 让我们返回一个空数组/集合,例如vararg或非空列表/集合/映射参数。
if (paramType.isArray()) {
return Array.newInstance(paramType.getComponentType(), 0);
}
else if (CollectionFactory.isApproximableCollectionType(paramType)) {
return CollectionFactory.createCollection(paramType, 0);
}
else if (CollectionFactory.isApproximableMapType(paramType)) {
return CollectionFactory.createMap(paramType, 0);
}
}
throw ex;
}
}
resolveDependency()
我们来看 resolveAutowiredArgument()
代码块的 2
中。
解析指定依赖,这边的 DependencyDescriptor
主要是封装了依赖的方法和参数的信息
这块我们来看 DefaultListableBeanFactory
中的实现:
@Override
@Nullable
public Object resolveDependency(
DependencyDescriptor descriptor,
@Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
// 1.javaUtilOptionalClass类注入的特殊处理
return createOptionalDependency(descriptor, requestingBeanName);
}
// 2.ObjectFactory类注入的特殊处理
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// 3.javaxInjectProviderClass类注入的特殊处理
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 4.通用类注入的处理
// 4.1 如有必要,请获取延迟解析代理
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 4.2 解析依赖关系,返回的result为创建好的依赖对象的bean实例
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
doResolveDependency()
我们来看 resolveDependency()
代码块的 4.2
中。
解析依赖关系,返回的 result 为创建好的依赖对象的 bean 实例。
@Nullable
public Object doResolveDependency(
DependencyDescriptor descriptor,
@Nullable String beanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) throws BeansException {
// 1. 设置当前的descriptor(存储了方法参数等信息)为当前注入点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
// 2. 如果是ShortcutDependencyDescriptor,则直接通过getBean方法获取Bean实例,并返回;否则返回null
/* 通过构造函数注入依赖的 bean 实例的整个过程是不会出现涉及到 ShortcutDependencyDescriptor 的。 ShortcutDependencyDescriptor 主要用于 @Autowire 注解, 在解析 @Autowire 注解的时候,当第一次注入依赖的 bean 实例后, 会将该依赖的 bean 的信息封装成 ShortcutDependencyDescriptor , 放到缓存中去,下一次需要依赖注入该 bean 时,可以直接快速的拿到该 bean 实例。 */
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 3. 拿到descriptor包装的方法的参数类型(通过参数索引定位到具体的参数)
Class<?> type = descriptor.getDependencyType();
// 4. 用于支持spring中新增的注解@Value(确定给定的依赖项是否声明Value注解,如果有则拿到值)
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 4.1 如果使用了@Value注解,则将解析到的值转换成所需的类型并返回
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 5. 解析MultipleBean(下文的MultipleBean都是指类型为:Array、Collection、Map)
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
// 5.1 如果确实是容器类型的属性,则直接返回解析结果
return multipleBeans;
}
// 6. 查找与所需类型匹配的Bean实例(matchingBeans,key:beanName;value:匹配的bean实例,或者匹配的bean实例的类型)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 6.1 如果require属性为true,而找到的匹配Bean却为空则抛出异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
// 6.2 如果require属性为false,而找到的匹配Bean却为空,则返回null
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
// 7. 非MultipleBean,但是有多个候选者
// 7.1 从多个候选者中选出最优的那个
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
// 7.2 拿到autowiredBeanName对应的value(bean实例或bean实例类型)
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// 8. 只找到了一个候选者,则直接使用该候选者
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
// 9. 将依赖的beanName加到autowiredBeanNames中
autowiredBeanNames.add(autowiredBeanName);
}
// 10. 如果instanceCandidate为Class,则instanceCandidate为bean实例的类型,执行descriptor.resolveCandidate方法,
// 通过getBean方法获取bean实例并返回;如果instanceCandidate不是Class,则instanceCandidate为bean实例,直接返回该实例
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
// 11. 执行结束,将注入点修改成原来的注入点
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
findAutowireCandidates()
我们来看 resolveDependency()
代码块的 6
中。
查找与所需类型匹配的Bean实例(名为matchingBeans
的map,key:beanName;value:匹配的bean实例
,或者匹配的bean实例的类型
)
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, // bd的beanName
Class<?> requiredType, // 要查找的bean的实际类型(可能是数组组件类型或集合元素类型)
DependencyDescriptor descriptor // 描述要解决的依赖关系
) {
// 1. 获取给定类型的所有beanName,包括在祖先工厂中定义的beanName
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
// 2.首先从已经解析的依赖关系缓存中寻找是否存在我们想要的类型
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
Class<?> autowiringType = classObjectEntry.getKey();
// 2.1 autowiringType是否与requiredType相同,或者是requiredType的超类、超接口
if (autowiringType.isAssignableFrom(requiredType)) {
// 2.2 如果requiredType匹配,则从缓存中拿到相应的自动装配值(bean实例)
Object autowiringValue = classObjectEntry.getValue();
// 2.3 根据给定的所需类型解析给定的自动装配值
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
// 2.4 将autowiringValue放到结果集中,此时的value为bean实例
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
// 3.遍历从容器中获取到的类型符合的beanName
for (String candidate : candidateNames) {
// isAutowireCandidate:判断是否有资格作为依赖注入的候选者
// 3.1 如果不是自引用 && candidate有资格作为依赖注入的候选者
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
// 3.2 将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// 4.如果结果为空 && type不是MultipleBean(Array、Collection、Map),则使用降级匹配
if (result.isEmpty()) {
boolean multiple = indicatesMultipleBeans(requiredType);
// Consider fallback matches if the first pass failed to find anything...
// 4.1 使用降级匹配(跟正常匹配类似)
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate)
&& isAutowireCandidate(candidate, fallbackDescriptor)
&& (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !multiple) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
// 5.如果使用降级匹配结果还是空,则考虑自引用
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
// 5.1 如果是自引用 && (descriptor不是MultiElementDescriptor || beanName不等于候选者)
// && candidate允许依赖注入,则将候选者添加到result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
// 6.返回符合条件的候选者
return result;
}
isAutowireCandidate()
我们来看 findAutowireCandidates()
代码块的 3.1
中。
判断是否有资格作为依赖注入的候选者。
对于Spring依赖注入(DI
)核心接口AutowireCandidateResolver
的解析博客文章:Spring依赖注入(DI)核心接口AutowireCandidateResolver深度分析,解析@Lazy、@Qualifier注解的原理【享学Spring】
// DefaultListableBeanFactory 792
@Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
/* getAutowireCandidateResolver: 返回BeanFactory的@Autowire解析器, 开启注解后的解析器为:ContextAnnotationAutowireCandidateResolver */
// 解析beanName对应的bean是否有资格作为候选者
return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}
// DefaultListableBeanFactory 806
protected boolean isAutowireCandidate(
String beanName,
DependencyDescriptor descriptor,
AutowireCandidateResolver resolver
) throws NoSuchBeanDefinitionException {
// 1.解析beanName,去掉FactoryBean的修饰符“&”
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
if (containsBeanDefinition(bdName)) {
// 2.beanDefinitionMap缓存中存在beanDefinitionName:通过beanDefinitionName缓存拿到MergedBeanDefinition,
// 将MergedBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
}
else if (containsSingleton(beanName)) {
// 3.singletonObjects缓存中存在beanName:使用beanName构建RootBeanDefinition作为参数,解析beanName是否有资格作为候选者
return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
// 4.在beanDefinitionMap缓存和singletonObjects缓存中都不存在,则在parentBeanFactory中递归解析beanName是否有资格作为候选者
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver);
}
else if (parent instanceof ConfigurableListableBeanFactory) {
// If no DefaultListableBeanFactory, can't pass the resolver along.
return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor);
}
else {
return true;
}
}
protected boolean isAutowireCandidate(
String beanName,
RootBeanDefinition mbd,
DependencyDescriptor descriptor,
AutowireCandidateResolver resolver
) {
// 1.解析beanName,去掉FactoryBean的修饰符“&”
String bdName = BeanFactoryUtils.transformedBeanName(beanName);
// 2.解析mbd的beanClass
resolveBeanClass(mbd, bdName);
if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
// 3.如果缓存中已经存在解析的构造函数或工厂方法,则解析mbd中的工厂方法,并替换掉缓存中的方法
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
BeanDefinitionHolder holder =
(beanName.equals(bdName) ?
this.mergedBeanDefinitionHolders.computeIfAbsent(
beanName,
key ->
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
// 4.使用resolver解析器解析mbd是否有资格作为依赖注入的候选者
return resolver.isAutowireCandidate(holder, descriptor);
}
resolver.isAutowireCandidate()
我们来看 isAutowireCandidate()
最后一个四个入参的重载方法的 4
中。
根据AutowireCandidateResolver
的不同实现来看一下代码。
这里我们可以主要看一下 QualifierAnnotationAutowireCandidateResolver
的实现,因为它是 ContextAnnotationAutowireCandidateResolver
的父类。
// AutowireCandidateResolver 44
default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
// GenericTypeAwareAutowireCandidateResolver 64
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
// If explicitly false, do not proceed with any other checks...
// 1. 如果父类返回false,则直接返回false
return false;
}
// 2. descriptor为空 || bdHolder的类型与descriptor的类型匹配,则返回true
return checkGenericTypeMatch(bdHolder, descriptor);
}
// QualifierAnnotationAutowireCandidateResolver 145 (ContextAnnotationAutowireCandidateResolver父类)
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 1. 调用父类方法判断此bean是否可以自动注入到其他bean
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
if (match) {
// 2. @Qualifiers注解检查
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
if (match) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
Method method = methodParam.getMethod();
if (method == null || void.class == method.getReturnType()) {
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
return match;
}
// SimpleAutowireCandidateResolver 41
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
// 获取此bean是否可以自动注入到其他bean(autowireCandidate属性),默认为true,一般不修改,因此这边返回true
// -> private boolean autowireCandidate = true;
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
addCandidateEntry()
好了,我们现在回到之前findAutowireCandidates()
的 isAutowireCandidate()
方法后面。
在 findAutowireCandidates()
的 3.2
中。
将候选者添加到result中。
当被依赖注入的属性是 MultipleBean
(Array、Collection、Map)类型,生成的依赖描述类型是 MultiElementDescriptor
,因此所有的候选者均是合格的,所以会当场实例化他们。而如果属性的类型是非 MultipleBean
,那么可能是从多个候选者中挑一个最合适的,因此此时实例化他们就不合适了,最终会把最合适的那个实例化,如果没有合格的则不应该实例化。
private void addCandidateEntry(
Map<String, Object> candidates,
String candidateName,
DependencyDescriptor descriptor,
Class<?> requiredType
) {
// 1.如果descriptor为MultiElementDescriptor类型(即注入的对象是集合那种的,也是从容器中直接取)
if (descriptor instanceof MultiElementDescriptor) {
// 2.1 resolveCandidate: 通过candidateName获取对应的bean实例
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
if (!(beanInstance instanceof NullBean)) {
// 2.2 将beanName -> bean实例 的映射添加到candidates(此时的value为bean实例)
candidates.put(candidateName, beanInstance);
}
}
// 3. 这个时候这个bean已经注册好了
else if (containsSingleton(candidateName) ||
(descriptor instanceof StreamDependencyDescriptor &&
((StreamDependencyDescriptor) descriptor).isOrdered())) {
// 直接从容器中取
Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
// 4. 将beanName -> bean实例的类型 的映射添加到candidates(此时的value为bean实例的类型)
// 调用对应的getType方法,然后put到对应候选集合中
candidates.put(candidateName, getType(candidateName));
}
}
determineAutowireCandidate()
我们再回到 doResolveDependency()
代码块的 7.1
中。
@Nullable
protected String determineAutowireCandidate(
Map<String, Object> candidates,
DependencyDescriptor descriptor
) {
Class<?> requiredType = descriptor.getDependencyType();
// 1. 根据@Primary注解来选择最优解
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 2. 根据@Priority注解来选择最优解
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// Fallback
// 3. 如果通过以上两步都不能选择出最优解,则使用最基本的策略
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
// 3.1 containsValue:首先如果这个beanInstance已经由Spring注册过依赖关系,则直接使用该beanInstance作为最优解,
// 3.2 matchesBeanName:如果没有注册过此beanInstance的依赖关系,则根据参数名称来匹配,
// 如果参数名称和某个候选者的beanName或别名一致,那么直接将此bean作为最优解
if ((beanInstance != null &&
this.resolvableDependencies.containsValue(beanInstance)) ||
// candidateName不为空 && candidateName与beanName相等 || beanName有别名与candidateName相等,则返回true
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
// 4.没有找到匹配的候选者,则返回null
return null;
}
determinePrimaryCandidate() & determineHighestPriorityCandidate()
根据@Primary注解来选择最优解 和 根据@Priority注解来选择最优解 两个方法。
先来看 determinePrimaryCandidate
的实现:
@Nullable
protected String determinePrimaryCandidate(
Map<String, Object> candidates,
Class<?> requiredType
) {
String primaryBeanName = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
// 2.判断候选者bean是否使用了@Primary注解:如果candidateBeanName在当前BeanFactory中存在BeanDefinition,
// 则判断当前BeanFactory中的BeanDefinition是否使用@Primary修饰;否则,在parentBeanFactory中判断
if (isPrimary(candidateBeanName, beanInstance)) {
if (primaryBeanName != null) {
// 3.走到这边primaryBeanName不为null,代表标识了@Primary的候选者不止一个,则判断BeanName是否存在于当前BeanFactory
// candidateLocal:candidateBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean candidateLocal = containsBeanDefinition(candidateBeanName);
// primaryLocal:primaryBeanName是否在当前BeanFactory的beanDefinitionMap缓存中
boolean primaryLocal = containsBeanDefinition(primaryBeanName);
if (candidateLocal && primaryLocal) {
// 3.1 如果当前BeanFactory中同一个类型的多个Bean,不止一个Bean使用@Primary注解,则抛出异常
throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
"more than one 'primary' bean found among candidates: " + candidates.keySet());
}
else if (candidateLocal) {
// 3.2 candidateLocal为true,primaryLocal为false,则代表primaryBeanName是parentBeanFactory中的Bean,
// candidateBeanName是当前BeanFactory中的Bean,当存在两个都使用@Primary注解的Bean,优先使用当前BeanFactory中的
primaryBeanName = candidateBeanName;
}
}
// 3.3 candidateLocal为false,primaryLocal为true,则代表primaryBeanName是当前BeanFactory中的Bean,
// candidateBeanName是parentBeanFactory中的Bean,因此无需修改primaryBeanName的值
else {
// 4.primaryBeanName还为空,代表是第一个符合的候选者,直接将primaryBeanName赋值为candidateBeanName
primaryBeanName = candidateBeanName;
}
}
}
// 5.返回唯一的使用@Primary注解的Bean的beanName(如果都没使用@Primary注解则返回null)
return primaryBeanName;
}
先来看 determineHighestPriorityCandidate
的实现:
@Nullable
protected String determineHighestPriorityCandidate(
Map<String, Object> candidates,
Class<?> requiredType
) {
// 用来保存最高优先级的beanName
String highestPriorityBeanName = null;
// 用来保存最高优先级的优先级值
Integer highestPriority = null;
// 1.遍历所有候选者
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateBeanName = entry.getKey();
Object beanInstance = entry.getValue();
if (beanInstance != null) {
// 2.拿到beanInstance的优先级
Integer candidatePriority = getPriority(beanInstance);
if (candidatePriority != null) {
if (highestPriorityBeanName != null) {
// 3.如果之前已经有候选者有优先级,则进行选择
if (candidatePriority.equals(highestPriority)) {
// 3.1 如果存在两个优先级相同的Bean,则抛出异常
throw new NoUniqueBeanDefinitionException(
requiredType, candidates.size(),
"Multiple beans found with the same priority ('" +
highestPriority +
"') among candidates: " +
candidates.keySet());
}
else if (candidatePriority < highestPriority) {
// 3.2 使用优先级值较小的Bean作为最优解(值越低,优先级越高)
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
else {
// 4.第一次有候选者有优先级
highestPriorityBeanName = candidateBeanName;
highestPriority = candidatePriority;
}
}
}
}
// 5.返回优先级最高的bean的beanName
return highestPriorityBeanName;
}
storeCache()
在 autowireConstructor()
代码块的 8
中。
是 ConstructorResolver
的静态内部类 ArgumentsHolder
的storeCache()
方法。
将解析的构造函数和参数放到缓存。
public void storeCache(RootBeanDefinition mbd, Executable constructorOrFactoryMethod) {
synchronized (mbd.constructorArgumentLock) {
// 将构造函数或工厂方法放到resolvedConstructorOrFactoryMethod缓存
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// constructorArgumentsResolved标记为已解析
mbd.constructorArgumentsResolved = true;
if (this.resolveNecessary) {
// 如果参数需要解析,则将preparedArguments放到preparedConstructorArguments缓存
mbd.preparedConstructorArguments = this.preparedArguments;
}
else {
// 如果参数不需要解析,则将arguments放到resolvedConstructorArguments缓存
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
到现在为止创建bean的过程应该大致完成了,后面为bean进行初始化并填充参数。
applyMergedBeanDefinitionPostProcessors()
又回到最初的起点,我们重新来看 docreateBean()
代码块的 6
中。
应用后置处理器 MergedBeanDefinitionPostProcessor
,允许修改 MergedBeanDefinition
。
调用 MergedBeanDefinitionPostProcessor
的 postProcessMergedBeanDefinition
方法,对指定 bean 的给定MergedBeanDefinition
进行后置处理,@Autowire
注解在这边对元数据进行预解析,之后会单独介绍。
protected void applyMergedBeanDefinitionPostProcessors(
RootBeanDefinition mbd,
Class<?> beanType,
String beanName
) {
// 1. 获取BeanFactory 中已注册的 BeanPostProcessor,这里同样使用了缓存
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
// 2.调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,
// 对指定bean的给定MergedBeanDefinition进行后置处理,@Autowire注解在这边对元数据进行预解析
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
addSingletonFactory() & getEarlyBeanReference()
我们重新来看 docreateBean()
代码块的 8
中。
用来提前曝光beanName的 ObjectFactory
,用于解决循环引用。
// addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 1.如果beanName不存在于singletonObjects缓存中
if (!this.singletonObjects.containsKey(beanName)) {
// 2.将beanName和singletonFactory注册到singletonFactories缓存(beanName -> 该beanName的单例工厂)
this.singletonFactories.put(beanName, singletonFactory);
// 3.移除earlySingletonObjects缓存中的beanName(beanName -> beanName的早期单例对象)
this.earlySingletonObjects.remove(beanName);
// 4.将beanName注册到registeredSingletons缓存(已经注册的单例集合)
this.registeredSingletons.add(beanName);
}
}
}
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 1. mbd不是合成 && 存在InstantiationAwareBeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 2. 允许SmartInstantiationAwareBeanPostProcessor调用getEarlyBeanReference返回指定bean的早期引用
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
// 3. 返回要作为bean引用公开的对象,如果没有SmartInstantiationAwareBeanPostProcessor修改,则返回的是入参的bean对象本身
return exposedObject;
}
populateBean()【重点】
我们重新来看 docreateBean()
代码块的 9
中。
对bean进行属性填充。其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例。
大概流程如下:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
方法,可以决定程序是否继续进行属性填充。只要有一个InstantiationAwareBeanPostProcessor
返回false,都会终止属性填充的过程。- 根据注入类型(
name
或type
),提取依赖的bean,并统一存入到propertyValues
中。 - 应用
InstantiationAwareBeanPostProcessor.postProcessProperties
和InstantiationAwareBeanPostProcessor.postProcessPropertyValues
方法,对属性获取完毕填充前对属性的再次处理。 - 将所有
propertyValues
中的属性填充至BeanWrapper
中。
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 1. bw为空时的处理
if (bw == null) {
// 1.1 检查是否存在属性值
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 1.2 跳过空属性值的属性填充
// Skip property population phase for null instance.
return;
}
}
// 【翻译注释】在设置属性之前,为任何实例化WarebeanPostProcessor提供修改bean状态的机会。例如,这可以用于支持字段注入的样式。
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
// 2. mbd不是合成的 && 容器中存在InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 3.2 在bean实例化后,属性填充之前被调用,允许修改bean的属性,如果执行失败,则跳过之后的属性填充
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 3. 返回此bean的属性值
/* pvs是一个MutablePropertyValues实例, 里面实现了PropertyValues接口,提供属性的读写操作实现, 同时可以通过调用构造函数实现深拷贝,里面存在一个propertyValueList 举例:propertyValue:key->value="xxx"->RuntimeBeanReference("<xxx>") */
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 4. 解析自动装配模式为AUTOWIRE_BY_NAME和AUTOWIRE_BY_TYPE(现在几乎不用)
/* 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置 */
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
// 4.1 解析autowireByName的注入
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 4.2 解析autowireByType的注入
autowireByType(beanName, mbd, bw, newPvs);
}
// 结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 5.BeanFactory是否注册过InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 6.是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
// 7. 如果注册过InstantiationAwareBeanPostProcessors
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 7.1 遍历注册过的InstantiationAwareBeanPostProcessors
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 7.2 调用postProcessProperties对值进行处理
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 7.3 调用postProcessPropertyValues对值进行处理
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
// 8. 如果需要依赖检查
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 8.1 依赖检查,对应 depends-on 属性,3.0 已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 9. 将属性应用到bean中
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,
// 注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
autowireByName()
我们先来看根据name注入的代码吧,在 populateBean()
代码块的 4.1
中。
protected void autowireByName(
String beanName,
AbstractBeanDefinition mbd,
BeanWrapper bw,
MutablePropertyValues pvs
) {
// 1. 寻找beanWrapper中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 2. 校验是否存在`beanName = propertyName`的bean实例或者BeanDefinition
if (containsBean(propertyName)) {
// 3. 获取propertyName的bean实例对象
Object bean = getBean(propertyName);
// 4. 将属性名和属性值添加到pvs
pvs.add(propertyName, bean);
// 5. 注册依赖关系到缓存(beanName依赖propertyName)
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
unsatisfiedNonSimpleProperties()
我们看 autowireByName()
代码块的 1
中。
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
// 1.拿到mdb的属性值
PropertyValues pvs = mbd.getPropertyValues();
// 2.拿到bw的PropertyDescriptors
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
// 3.遍历bw的PropertyDescriptors
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && // pd用于写入属性值的方法不为空
!isExcludedFromDependencyCheck(pd) && // pd不是从依赖性检查中排除的bean属性
!pvs.contains(pd.getName()) && // pd不包含在pvs里
!BeanUtils.isSimpleProperty(pd.getPropertyType()) // pd的属性类型不是“简单”属性(基础类型、枚举、Number等)
) {
// 4.1 符合条件,则添加pd的name到result中
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
BeanUtils.isSimpleProperty
主要是用来判定属性是否为简单类型,主要涵盖基本类型及其包装类,Number,Date等…
// BeanUtils 643
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
// clazz是简单值类型 || ( clazz是数组 && clazz的组件类型为简单值类型)
return isSimpleValueType(type) ||
// getComponentType:返回数组的组件类型,例如: String[] 返回 String.class,如果是非数组,则返回null
(type.isArray() && isSimpleValueType(type.getComponentType()));
}
// BeanUtils 657
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
// ClassUtils 493
public static boolean isPrimitiveOrWrapper(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
// clazz为基础类型(8个包装类 + Void) || clazz是基础类型的封装类(8个包装类 + Void)
return (clazz.isPrimitive() || isPrimitiveWrapper(clazz));
}
// ClassUtils 479
public static boolean isPrimitiveWrapper(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return primitiveWrapperTypeMap.containsKey(clazz);
}
private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new IdentityHashMap<>(9);
static {
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
primitiveWrapperTypeMap.put(Byte.class, byte.class);
primitiveWrapperTypeMap.put(Character.class, char.class);
primitiveWrapperTypeMap.put(Double.class, double.class);
primitiveWrapperTypeMap.put(Float.class, float.class);
primitiveWrapperTypeMap.put(Integer.class, int.class);
primitiveWrapperTypeMap.put(Long.class, long.class);
primitiveWrapperTypeMap.put(Short.class, short.class);
primitiveWrapperTypeMap.put(Void.class, void.class);
}
containsBean()
我们看 autowireByName()
代码块的 2
中。
校验是否存在beanName = propertyName
的 bean
实例或者 BeanDefinition
。
@Override
public boolean containsBean(String name) {
// 1. 将name转换为真正的beanName(比如:前缀&)
String beanName = transformedBeanName(name);
// 2. 检查singletonObjects缓存 或者 beanDefinitionMap缓存中是否存在beanName
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
// 3. name不带&前缀,或者是FactoryBean,则返回true
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent.
// 4. 没有找到则检查parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}
autowireByType()
我们先来看根据type注入的代码吧,在 populateBean()
代码块的 4.2
中。
protected void autowireByType(
String beanName,
AbstractBeanDefinition mbd,
BeanWrapper bw,
MutablePropertyValues pvs
) {
// 获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 1. 寻找beanWrapper中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 2. 遍历所有需要依赖注入的属性
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// 【翻译注释】不要尝试为类型对象按类型自动关联:永远没有意义,即使它在技术上是一个不令人满意的非简单属性。
// 如果是Object类型不进行装配
if (Object.class != pd.getPropertyType()) {
// 3. 获取指定属性的set方法,封装成MethodParameter(必须有set方法才能通过属性来注入)
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// 【翻译注释】在优先后处理器的情况下,不允许使用eager init进行类型匹配。
// 定义是否允许懒加载
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
// 4. 将MethodParameter的方法参数索引信息封装成DependencyDescriptor
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 5. 解析当前属性所匹配的bean实例,并把解析到的bean实例的beanName存储在autowiredBeanNames中
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
// 6. 如果找到了依赖的bean实例,将属性名和bean实例放到pvs中
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 7.注册依赖关系,beanName依赖autowiredBeanName
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
applyPropertyValues()
我们看 populateBean()
代码块的 9
中。
将属性应用到bean中。
/* 【注释翻译】 应用给定的属性值,解析对该bean工厂中其他bean的任何运行时引用。 必须使用深度复制,因此我们不会永久修改此属性。 */
protected void applyPropertyValues(
String beanName,
BeanDefinition mbd,
BeanWrapper bw,
PropertyValues pvs
) {
// 为空直接返回
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
// 1. 获取属性值列表
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 1.1 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到BeanWrapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
// 1.2 如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 2.1 创建BeanDefinitionValueResolver解析器,用来解析未被解析的PropertyValue。
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
// 2.2 创建深层拷贝副本,用于存放解析后的属性值
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 3. 遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
// 3.1 如果pv已经包含转换的值,则直接添加到deepCopy
deepCopy.add(pv);
}
// 3.2 否则,进行转换
else {
// 3.2.1 拿到pv的原始属性名
String propertyName = pv.getName();
// 3.2.1 拿到pv的原始属性值
Object originalValue = pv.getValue();
/* (这是spring5.2新增的) AutowiredPropertyMarker.INSTANCE = new AutowiredPropertyMarker(); 它的【注释】为: 单个自动连接属性值的简单标记类, 将添加到特定bean属性的BeanDefinition#getPropertyValues()中。 在运行时,它将被相应bean属性的write方法的DependencyDescriptor替换, 最终通过AutowireCapableBeanFactory#resolveDependency步骤解析。 */
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
// 获取对应propertyName名称属性的writeMethod
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
// 封装writeMethod为DependencyDescriptor
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 3.2.2 使用解析器解析原始属性值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 3.2.3 判断该属性是否可转换
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 3.2.4 如果可转换,则转换指定目标属性的给定值
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 【翻译注释】可能将转换后的值存储在合并的bean定义中,以避免对每个创建的bean实例进行重新转换。
// 3.2.5 在合并的BeanDefinition中存储转换后的值,以避免为每个创建的bean实例重新转换
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible &&
originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection ||
ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
// 标记MutablePropertyValues的converted为true
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 4.设置bean的属性值为deepCopy
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
initializeBean()【重点】
在 doCreateBean()
代码块的 10
中,此时的bean属性已经填充完成,现在就可以进行bean的初始化工作了。
我们可以将这个方法分为四个步骤:
- 对实现
Aware
接口对bean的设置。 - 依次回调bean后置处理器的
postProcessBeforeInitialization
方法。 - 执行实现了
InitializingBean
或者用户自定义的init
方法方法。 - 依次回调bean后置处理器的
postProcessAfterInitialization
方法。
/* 【翻译注释】 初始化给定的bean实例,应用工厂回调、init方法和bean后处理器。 对于传统定义的bean,从{@link#createBean}调用;对于现有bean实例,从{@link#initializeBean}调用。 */
protected Object initializeBean(
String beanName,
Object bean,
@Nullable RootBeanDefinition mbd
) {
// 1.激活Aware方法
if (System.getSecurityManager() != null) {
/* - AccessController.doPrivileged意思是这个是特别的,不用做权限检查。 - 在什么地方会用到呢:加入1.jar中有类可以读取一个文件,现在我们要使用1.jar去做这个事情。 但是我们的类本生是没有权限去读取那个文件的,一般情况下就是眼睁睁的看着了。 但是java提供了doPrivileged.在1.jar中如果读取文件的方法是通过doPrivileged来实现的。 就不会有后面的检查了,现在我们就可以使用1.jar去读取那个文件了。 - 即在方法体内执行方法拥有“特权”。 */
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 如果实现了Aware接口,就对该bean进行一些设置。
// 比如实现了BeanNameAware接口,那么对其bean的属性beanName上set上对应的beanName。
// 如果实现了BeanFactoryAware接口,那么对其beanFactory属性设置上创建该bean使用的bean工厂。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2.在初始化前应用BeanPostProcessor的postProcessBeforeInitialization方法,允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3.调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 4.在初始化后应用BeanPostProcessor的postProcessAfterInitialization方法,允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
// 5.返回wrappedBean
return wrappedBean;
}
invokeAwareMethods()
我们一起来看 initializeBean()
代码块的 1
中。
看一下具体激活Aware方法的实现,这里的实现比较简单。
进入 initializeBean
方法后,不管是走带有安全检查的if分支还是走不需要检查的else分支,第一步的核心方法都是执行 invokeAwareMethods(beanName, bean)
方法。实现 Aware
接口用于让bean能拥有某些额外的感知能力。
比如实现了 BeanNameAware
接口,那么对其bean的属性beanName上set上对应的beanName,那么该bean就可以知道自己的beanName是什么。
如果实现了 BeanFactoryAware
接口,那么对其beanFactory属性设置上创建该bean使用的bean工厂,那么该bean就可以感知到创建自己的是哪一个bean工厂。
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// BeanNameAware: 实现此接口的类想要拿到beanName,因此我们在这边赋值给它
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoaderAware:实现此接口的类想要拿到beanClassLoader,因此我们在这边赋值给它
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// BeanFactoryAware: 实现此接口的类想要拿到 BeanFactory,因此我们在这边赋值给它
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
applyBeanPostProcessorsBeforeInitialization()
我们一起来看 initializeBean()
代码块的 2
中。
在初始化前应用 BeanPostProcessor
的 postProcessBeforeInitialization
方法。
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1. 遍历所有注册的BeanPostProcessor实现类,调用postProcessBeforeInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2. 在bean初始化方法执行前,调用postProcessBeforeInitialization方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
在前面介绍 BeanPostProcessor
的时候,就知道了 postProcessBeforeInitialization
这个方法。
在不引入 AOP
的情况下,重要的 postProcessBeforeInitialization
有以下3个:
ApplicationContextAwareProcessor
ImportAwareBeanPostProcessor
CommonAnnotationBeanPostProcessor
我们先来看一下 ApplicationContextAwareProcessor
。
我们经常通过实现 ApplicationContextAware
接口来拿到 ApplicationContext
。我们之所以能拿到 ApplicationContext
,就是在这下边的代码实现中被赋值了。
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/** * Create a new ApplicationContextAwareProcessor for the given context. */
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 快速检查,如果没有实现对应接口则直接返回bean实例
if (!(bean instanceof EnvironmentAware ||
bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware ||
bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware ||
bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)
) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 有“特权”地调用Aware接口
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
// 调用Aware接口
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
我们再来看一下 ImportAwareBeanPostProcessor
。
它是 ConfigurationClassPostProcessor
的内部静态类,在前面已经说过它的注册时机了。
如果实现了 ImportAware
接口,在 postProcessBeforeInitialization
中首先解析出 importingClass
,使得bean能感知到 importingClass
。
private static class ImportAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
private final BeanFactory beanFactory;
public ImportAwareBeanPostProcessor(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
// 【注释翻译】在AutowiredAnnotationBeanPostProcessor的postProcessProperties方法尝试自动连接其他配置bean之前注入BeanFactory
if (bean instanceof EnhancedConfiguration) {
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
}
最后我们来看一下 CommonAnnotationBeanPostProcessor
。
CommonAnnotationBeanPostProcessor
会实际调用 InitDestroyAnnotationBeanPostProcessor
的 postProcessBeforeInitialization
方法执行。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 获得声明周期的元数据对象,里面存放有bean中 @PostConstruct 和 @PreDestroy 注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 执行@PostConstruct对应的方法集,比如Human.class中对应的是 void com.Hodey.learn.bean.Human.init()这个1个方法
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
首先通过 findLifecycleMetadata(bean.getClass())
寻找到本类中属于声明周期回调的注解元数据对象。也就是寻找本类中是否有 @PostConstruct
和 @PreDestroy
注解的方法。然后对其中的 @PostConstruct
注解方法进行回调操作。
public void invokeInitMethods(Object target, String beanName) throws Throwable {
Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
Collection<LifecycleElement> initMethodsToIterate =
(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
// 只要存在@PostConstruct注解方法,就执行回调
if (!initMethodsToIterate.isEmpty()) {
for (LifecycleElement element : initMethodsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
}
element.invoke(target);
}
}
}
它先获取 @PostConstruct
对应的方法集 checkedInitMethods
,然后再for循环中依次通过 element.invoke(target)
,在内部通过反射执行。
比如以 Adam.class
举例,会调用 private void init(){ name = "Adam"; }
中的 name = "Adam";
方法对 name 赋值。
invokeInitMethods()
我们一起来看 initializeBean()
代码块的 3
中。
如果bean实现了 InitializingBean
或者用户自定义的 init
方法,那么调用这些初始化方法对bean的属性进行一些个性化设置。
protected void invokeInitMethods(
String beanName,
Object bean,
@Nullable RootBeanDefinition mbd)
throws Throwable {
// 1. 首先检查bean是否实现了InitializingBean接口,如果是的话调用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean &&
(mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))
) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
// 2.调用afterPropertiesSet方法
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null &&
bean.getClass() != NullBean.class
) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) && // 存在 init 方法
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 3.调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
如果是调用自定义的 init
初始化方法,那我们来看一下他的实现。
protected void invokeCustomInitMethod(
String beanName,
Object bean,
RootBeanDefinition mbd)
throws Throwable {
// 1.拿到初始化方法的方法名
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
// 2.根据方法名拿到方法
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
// 3.如果不存在initMethodName对应的方法
if (initMethod == null) {
// 3.1 强制执行初始化方法(默认为强制), 则抛出异常
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
// 3.2 如果设置了非强制,找不到则直接返回
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
// 从缓存中获取该方法,并调用初始化方法
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
// 存在安全管理器
AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
}
);
try {
AccessController.doPrivileged(
(PrivilegedExceptionAction<Object>) () -> methodToInvoke.invoke(bean),
getAccessControlContext()
);
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
else {
// 不存在安全管理器
try {
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
applyBeanPostProcessorsAfterInitialization()
我们一起来看 initializeBean()
代码块的 4
中。
最后,再回调所有bean后置处理器的 postProcessAfterInitialization
方法。
Spring AOP的代理实现场所就在这里,由于这边文章主要介绍Spring IOC,AOP的知识下次再整理(IOC就让我追代码追了好久QAQ,追《开端》都没追这么勤)。
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1. 遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2. 在bean初始化方法执行后,调用postProcessAfterInitialization方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
执行完成 postProcessAfterInitialization
后,会返回最终经过这些后置处理器加工后的bean返回到 doCreateBean
方法中。接下来还要执行另外一种声明周期方法的注册。
registerDisposableBeanIfNecessary()
我们一起来看 doCreateBean()
代码块的 12
中。
注册用于销毁的 bean,执行销毁操作的有三种:
- 自定义 destroy 方法
- DisposableBean 接口
- DestructionAwareBeanPostProcessor
/* 【注释翻译】 将给定bean添加到此工厂中的一次性bean列表中, 注册其DisposableBean接口 and/or 在工厂关闭时调用的给定销毁方法(如果适用)。只适用于单例。 */
protected void registerDisposableBeanIfNecessary(
String beanName,
Object bean,
RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 1.mbd的scope不是prototype && 给定的bean需要在关闭时销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
/* 【注释翻译】 注册一个DisposableBean实现, 该实现执行给定bean的所有销毁工作: DestructionAwareBeanPostProcessors、DisposableBean接口、自定义销毁方法。 */
// 2.单例模式下注册用于销毁的bean到disposableBeans缓存,执行给定bean的所有销毁工作:
// DestructionAwareBeanPostProcessors,DisposableBean接口,自定义销毁方法
// 2.1 DisposableBeanAdapter:使用DisposableBeanAdapter来封装用于销毁的bean
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// 3.自定义scope处理
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
requiresDestruction()
我们一起来看 registerDisposableBeanIfNecessary()
代码块的 1
中。
判断是否需要注册销毁方法的条件有两个,!mbd.isPrototype() && requiresDestruction(bean, mbd)
。
我们来看一下requiresDestruction
是如何确定该bean需要在关闭时销毁:
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class && // 不是NullBean.class
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || // 判断bean是否有destroy方法
(hasDestructionAwareBeanPostProcessors() && // 判断当前BeanFactory是否注册过DestructionAwareBeanPostProcessor
DisposableBeanAdapter.hasApplicableProcessors( // 是否存在适用于bean的DestructionAwareBeanPostProcessor
bean,
getBeanPostProcessorCache().destructionAware
)
)
)
);
}
我们来看一下这三个方法:
DisposableBeanAdapter.hasDestroyMethod(bean, mbd)
:判断bean是否有destroy
方法。hasDestructionAwareBeanPostProcessors()
:判断当前BeanFactory是否注册过DestructionAwareBeanPostProcessor
。DisposableBeanAdapter.hasApplicableProcessors
:是否存在适用于bean的DestructionAwareBeanPostProcessor
。
// DisposableBeanAdapter 325
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
// 1. 如果bean实现了DisposableBean接口 || bean是AutoCloseable实例。直接返回true
// 因为这两个接口都有关闭的方法
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
// 2. 如果不满足上方条件,进行有必要的推断
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
}
// DisposableBeanAdapter 347
@Nullable
private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
// 1. 拿到bean自定义的destroy方法名
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
// 2. 如果自定义的destroy方法名为“(inferred)”(该名字代表需要我们自己去推测destroy的方法名),
// 则检查该bean是否存在方法名为“close”或“shutdown”的方法,如果存在,则返回true
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
try {
// CLOSE_METHOD_NAME = "close"
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
// SHUTDOWN_METHOD_NAME = "shutdown"
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
}
// 3. 如果destroyMethodName不为空,则返回true
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
// AbstractBeanFactory 1021
protected boolean hasDestructionAwareBeanPostProcessors() {
return !getBeanPostProcessorCache().destructionAware.isEmpty();
}
// DisposableBeanAdapter 308
public static boolean hasApplicableProcessors(Object bean, List<DestructionAwareBeanPostProcessor> postProcessors) {
if (!CollectionUtils.isEmpty(postProcessors)) {
// 1. 遍历所有的DestructionAwareBeanPostProcessor
for (DestructionAwareBeanPostProcessor processor : postProcessors) {
if (processor.requiresDestruction(bean)) {
// 2. 如果给定的bean实例需要通过此后处理器进行销毁,则返回true
return true;
}
}
}
return false;
}
registerDisposableBean() & DisposableBeanAdapter
我们一起来看 registerDisposableBeanIfNecessary()
代码块的 2.1
中。
注册 DisposableBean
。
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
DisposableBeanAdapter
,它是实际一次性Bean和可运行接口适配器,对给定Bean实例执行各种销毁步骤
。
我们在上述代码中构造了new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc)
,我们来看一下它的构造方法:
/* 为给定Bean创建一个新的一次性BeanAdapter */
public DisposableBeanAdapter(
Object bean,
String beanName,
RootBeanDefinition beanDefinition,
List<DestructionAwareBeanPostProcessor> postProcessors,
@Nullable AccessControlContext acc
) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
// 1. bean是否是DisposableBean实例 && 'destory'没有受外部管理的销毁方法
this.invokeDisposableBean =
(this.bean instanceof DisposableBean &&
!beanDefinition.isExternallyManagedDestroyMethod("destroy"));
// 2. beanDefinition 是否允许访问非公共构造函数和方法
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
// 3. 拿到自定义的destroy方法名
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (
// destroyMethodName 不为 null &&
// (bean是否是DisposableBean实例 && 'destory'没有受外部管理的销毁方法
// && destroyMethodName是'destroy') && destroyMethodName 不是外部受管理的销毁方法
destroyMethodName != null &&
!(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)
) {
this.destroyMethodName = destroyMethodName;
// 4. 根据beanDefinition是否允许访问非公共构造函数和方法的情况来查找最小参数(最好是none)的销毁方法对象
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
// 5. 如果 beanDefinition 配置的destroy方法为默认方法
if (beanDefinition.isEnforceDestroyMethod()) {
// 抛出Bean定义验证异常:不能找到名为'destroyMethodName'销毁方法在名为'beanName'的Bean中
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
if (destroyMethod.getParameterCount() > 0) {
// 5.拿到destroy方法的参数类型数组
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
// 6. 如果参数类型数组大于1
if (paramTypes.length > 1) {
// 6.1 抛出Bean定义验证异常:名为'destroyMethodName'销毁方法在名为'beanName'的Bean中有超过1个参数-不支持作为销毁方法
throw new BeanDefinitionValidationException(
"Method '" +
destroyMethodName +
"' of bean '" +
beanName +
"' has more than one parameter - not supported as destroy method");
}
// 7. 参数类型数组为 1 && 第一个参数类型不时Boolean类
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
// 7.1 抛出Bean定义验证异常:名为'destroyMethodName'销毁方法在名为'beanName'的Bean中不是接受一个boolean参数-不支持作为销毁方法
throw new BeanDefinitionValidationException(
"Method '" +
destroyMethodName +
"' of bean '" +
beanName +
"' has a non-boolean parameter - not supported as destroy method");
}
}
// 此时参数类型数组为 0
// 8. 获取destroyMethod相应的接口方法对象,如果找不到,则返回原始方法
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
// 9. 查找DestructionAwareBeanPostProcessors,并赋值给this.beanPostProcessors
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
// 代码块 9
@Nullable
private static List<DestructionAwareBeanPostProcessor> filterPostProcessors(
List<DestructionAwareBeanPostProcessor> processors,
Object bean
) {
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
if (!CollectionUtils.isEmpty(processors)) {
filteredPostProcessors = new ArrayList<>(processors.size());
// 1. 遍历所有的DestructionAwareBeanPostProcessor
for (DestructionAwareBeanPostProcessor processor : processors) {
if (processor.requiresDestruction(bean)) {
// 2. 如果给定的bean实例需要通过此后处理器进行销毁,则添加到filteredPostProcessors
filteredPostProcessors.add(processor);
}
}
}
return filteredPostProcessors;
}