ps:bean初始化相关的内容实在太多,不得已只好将其分成上下两篇来讲
此篇为下篇,各位看客最好先去读一下上篇再来看,不然有可能很迷糊
这里所说的bean是普通的单例bean,也就是通过@bean注解、配置文件、@Service注解 等等注入的bean,bean的初始化是SpringBoot启动流程中重要的组成部分之一。bean实例化都始于finishBeanFactoryInitialization(beanFactory)
方法,我们一起快速的定位到这个方法,版本不同具体路径可能不同,这里以2.1.9.RELEASE为准
启动类(application)->main方法 ->run方法 ->run方法 ->run方法 ->refreshContext方法 ->refresh方法 ->refresh方法 ->finishBeanFactoryInitialization方法
实例bean之前的流程,可以看之前的文章了解一下,对bean实例化理解会很有帮助
步骤1:必要组件的补全与配置冻结
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 一上来SpringBoot先判断了一种特殊的bean,conversionService类型的bean
//conversionService主要用于数据装换,例如把一个String转换成一个User类型的对象
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
//如果存在conversionService类型的bean,把这个bean对象存放到BeanFactory当中
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 判断是否设置了解析器,解析器可能会有多个,被缓存在EmbeddedValueResolver集合当中
//解析器会被用于解析配置文件、解析注解里面的特别值
//在先前的流程中我们已经注入过了,这段逻辑不会进入
//具体逻辑在《SpringBoot源码初学者(三)》的 步骤16中的 invokeBeanFactoryPostProcessors方法里
//这里没有详细说明,需要读者自己翻阅一下,最终在PlaceholderConfigurerSupport#doProcessProperties方法中会调用addEmbeddedValueResolver方法
if (!beanFactory.hasEmbeddedValueResolver()) {
//添加默认的EmbeddedValueResolver
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 在早期的时候对bean进行aop的织入,aop织入的一种手段,很少使用
//正常情况下是不会有这种bean,不过也是个知识点可以笔记记一下
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 清空临时加载器
beanFactory.setTempClassLoader(null);
//冻结配置
//在bean实例化的过程中不允许再向SpringBoot容器中添加新的bean定义
//步骤 2
beanFactory.freezeConfiguration();
//正式开始单例bean的实例化(不包括懒加载的bean)
//步骤 3 进入DefaultListableBeanFactory类的preInstantiateSingletons方法
beanFactory.preInstantiateSingletons();
}
步骤2:冻结配置
@Override
public void freezeConfiguration() {
//修改状态值,锁定住配置
this.configurationFrozen = true;
//将当前的bean定义的名称,复制到冻结配置记录中,用来标记正在实例化的bean
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
步骤3:实例化单例bean的预处理
@Override
public void preInstantiateSingletons() throws BeansException {
//打印日志 bean实例化的预处理开始了
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取所有的bean定义的名字
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历这些bean定义名字,循环逐个进行处理
for (String beanName : beanNames) {
//获取beanDefinition
//简单介绍一下beanDefinition,它是bean的源信息,对bean进行描述
//包括bean是否是单例的,是否是懒加载的,beanClass信息等等
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//如果这个bean定义显示,他不是抽象的 && 是单例的 && 不是懒加载,就进入bean的实例化逻辑
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是不是工厂bean
//步骤 4
if (isFactoryBean(beanName)) {
//获取bean对象(里面包含实例化bean的逻辑)
//FACTORY_BEAN_PREFIX是常量,值就是“&”
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//判断是否实现了FactoryBean接口
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
//如果是工厂bean需要判断,当前这个工厂是否需要立马就生产一个bean对象
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) {
//获取bean对象(里面包含实例化bean的逻辑)
//步骤 5
getBean(beanName);
}
}
}
else {
//获取bean对象(里面包含实例化bean的逻辑)
//步骤 5
getBean(beanName);
}
}
}
// 触发所有初始化完成的bean的回调方法
//逐一遍历
for (String beanName : beanNames) {
//获取单例实例
Object singletonInstance = getSingleton(beanName);
//只有“智能的初始化单例对象”才有回调方法
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
//执行回调方法,这里多个系统的安全权限的设置
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//执行回调方法
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
步骤4:判断是不是工厂bean
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
//将名称转换成beanName
//FactoryBean的Name与普通bean的Name并不一样
//FactoryBeanName是以“&”开头的,这里的操作就是把前面的“&”去掉,然后用得到的字符串再去别名对照表里面查询,如果没有别名,就是返回去掉“&”的字符串
String beanName = transformedBeanName(name);
//尝试从单例集合中获取到这个bean
Object beanInstance = getSingleton(beanName, false);
//如果能获取到Bean的实例
if (beanInstance != null) {
//判断bean实例是否实现了FactoryBean接口
return (beanInstance instanceof FactoryBean);
}
// 如果没找到单例的bean实例,就从其他地方进行检测
//不存在与bean定义 && 父级bean工厂实现了ConfigurableBeanFactory接口
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// 调用父级bean判断是否为工厂bean,这是个递归,逐层查询
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
//上面都找不到只能尝试从复合bean定义中判断
//复合bean:如果给定bean的定义是子bean定义,则通过与父bean合并,为给定bean返回一个RootBeanDefinition
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
步骤5:获取bean对象(里面包含实例化bean的逻辑)
@Override
public Object getBean(String name) throws BeansException {
//spring的老习惯了,一层套一层 老千层饼了
//步骤 6
return doGetBean(name, null, null, false);
}
步骤6:真·获取bean对象(超长方法警告!!!前方高能)
别害怕,慢慢看,大佬们也是一步步走过来的,如果退缩了水平也就限制住了
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//这个name可能是个FactoryBean的name
//FactoryBean的Name与普通bean的Name并不一样,会多一个前缀符“&”
//具体查看 步骤4 的中说明
final String beanName = transformedBeanName(name);
Object bean;
// 尝试直接从单例bean的集合中获取,getSingleton方法是从一个存放单例bean实例的集合中查询
//在每个单例bean实例化完成之后都会存入到该集合中
Object sharedInstance = getSingleton(beanName);
//第一次尝试获取某个bean的时候,sharedInstance必然为null
if (sharedInstance != null && args == null) {
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 + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// isPrototypeCurrentlyInCreation方法会检查,当前的这个bean是否在当前线程的其他地方正在被创建
//如果存在这种情况就会抛出异常
//判断方式很简单,springFactory中有个叫做prototypesCurrentlyInCreation的本地线程变量,里面存放着当前正在实例化中的bean的Name
if (isPrototypeCurrentlyInCreation(beanName)) {
//抛出异常,当前正在创建的Bean异常
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父级beanFactory,如果有父级beanFactory就尝试从父级beanFactory中获取bean
//因为很有可能父级beanFactory已经实例化过了这个bean,如果没有实例化过,那也没关系,实例化的功能就交给父级beanFactory完成
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 规范beanName,如果是别名就转换成真正的beanname,如果不是别名就原样输出
String nameToLookup = originalBeanName(name);
//这段逻辑都是为了更好的使用父级BeanFactory,最终的结果都是一样的
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方法 ,当然是父级BeanFactory的方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//最后一种,没有更多的信息,只能在父类中再跑一遍完整的getBean
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
//标记当前bean正在被创建
//步骤7
markBeanAsCreated(beanName);
}
try {
//获取Bean定义
//getMergedLocalBeanDefinition会先尝试从当前BeanFactory的mergedBeanDefinitions集合中获取bean定义
//如果仔细看了 步骤7 我们会知道bean定义的缓存已经从当前的BeanFactory中删除了
//所以他会去尝试获取一个最新的bean定义,或者是创建一个想的bean定义
//保证在bean是根据最新的bean定义创建出来的
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//判断RootBeanDefinition是否是抽象类,如果是抽象类就会抛出异常
checkMergedBeanDefinition(mbd, beanName, args);
// 获取当前Bean强制依赖的beanName
//通过@DependsOn或者depends-on配置的强制依赖
//DependsOn属性会在bean初始化之前优先初始化依赖的bean,起到bean顺序实例化的作用
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//逐一处理需要依赖的bean
for (String dep : dependsOn) {
//确定当前正在创建bean是否与需要依赖的bean进行了依赖注册
//如果他们之间已经有了依赖关系,说明他们之间存在循环依赖,就会进入下面的异常
//循环依赖检测原理: A实例化的时候注册依赖了B,
//当B实例化的时候会在依赖关系集合中检测是否和A已经发生了依赖,如果有则存在循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//进行依赖关系的注册,就是上面原理中提到的依赖注册
registerDependentBean(dep, beanName);
try {
//创建依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//下面的流程正式开始bean的实例化
//判断bean定义是否是单例的
if (mbd.isSingleton()) {
//获取单例bean,无法从缓存中获取,就是创建一个单例bean
//下面两个参数第一个是bean的名字,第二个参数是创建bean的逻辑
//如果没有学过lamdba,可能会对第二个参数有点疑惑,不要紧,先记住这里有个创建Bean的逻辑,然后进入到步骤8中
//点击getSingleton方法,步骤8
sharedInstance = getSingleton(beanName, () -> {
try {
//步骤9 创建bean对象
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// 销毁掉bean对象,抛出异常,然后关闭SpringBoot
destroySingleton(beanName);
throw ex;
}
});
//通过工厂bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//后面的流程是原型bean的处理,这里比较复杂,有兴趣可以先看看,不是目前我们要接触的,等我们后面学习到代理模式的时候再回头来看,先刷小怪,level够了 回头再来boss
else if (mbd.isPrototype()) {
//部分代码省略
............
}
}
}
return (T) bean;
}
步骤7:标记当前bean正在被创建
protected void markBeanAsCreated(String beanName) {
//alreadyCreated也是BeanFactory中的一个集合,里面存放着至少被实例化过1次的bean的Name
//这里也是典型的双层校验,兼顾性能和线程安全
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// 将bean的定义从BeanFactory中清除掉,防止在创建Bean的时候他的源元素定义被改变
//MergedBeanDefinition中的bean的定义相当于缓存
//如果bean的定义被改变了,这里不清除那么创建出来的bean就不是根据最新的定义创建的
//在后续的流程中会重新创建一个新的Bean定义
clearMergedBeanDefinition(beanName);
//将beanName加入到alreadyCreated集合汇总
this.alreadyCreated.add(beanName);
}
}
}
}
步骤8:获取单例bean
再次强调一下这里的第二个参数是创建bean的逻辑,是通过lamdba传过来的一串逻辑
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//关门上锁,保证单例的bean不会在同一时间创建2个
synchronized (this.singletonObjects) {
//尝试从缓存中获取bean的实例,如果有,后面就会直接返回结果了
Object singletonObject = this.singletonObjects.get(beanName);
//当然大多数情况下是没有的
if (singletonObject == null) {
//判断是否正在销毁
if (this.singletonsCurrentlyInDestruction) {
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 + "'");
}
//这里再次做一下检测,检测bean是否是被实例化排除的bean,或者bean是否已经在初始化了
//同时将beanName加入到singletonsCurrentlyInCreation集合中,singletonsCurrentlyInCreation集合中存放着长在实例化的单例bean
beforeSingletonCreation(beanName);
//单例Bean是否被创建的标识
boolean newSingleton = false;
//初始化 保存错误信息的容器,如果之前已经被初始化了就跳过
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//这里就很重要了
//singletonFactory就是当前方法的第二个参数,也就是创建bean的逻辑
//调用getObject方法,实际上就是在执行传过来的逻辑
//忘记的回到步骤6中再看一下
singletonObject = singletonFactory.getObject();
//改变单例bean被创建的标识
newSingleton = true;
}
catch (IllegalStateException ex) {
//再抢救一下,如果还是获取不到,那就没救了
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;
}
//将bean从正在创建的列表中删除,就是从singletonsCurrentlyInCreation集合中删除
afterSingletonCreation(beanName);
}
//如果成功的创建了单例bean
if (newSingleton) {
//将bean实例和beanName记录到容器中
//具体过程:
//1、加入到singletonObjects容器中
//2、从singletonFactories容器中移除
//3、从earlySingletonObjects容器中移除
//4、添加到registeredSingletons容器中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
这里把上面代码中一个重要的知识点做个说明防止大家没看懂
singletonObjects容器:专门存放单例bean实例的容器,key-value的结构,key为BeanName,value为bean的实例
singletonFactories容器:专门存放单例bean工厂的容器,key-value的结构,key为BeanName,value为bean的工厂
earlySingletonObjects容器:也是存放单例bean的容器,但是与singletonObjects不同,这个容器中存放的bean实例,可能还在创建当中,是提前曝光出来的bean实例,同来解决循环依赖的问题,当然不是所有的循环依赖都能被解决
registeredSingletons容器:按顺序存放已经注册的SingletonBean的名称
步骤9:创建bean实例
参数回顾:
beanName:bean名称
mbd:bean的定义,包含bean绝大部分的信息
args:主流程这里是null
@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;
//获取bean的class类型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
//克隆一次bean
mbdToUse = new RootBeanDefinition(mbd);
//重新设置bean的class类型
mbdToUse.setBeanClass(resolvedClass);
}
//设置方法重写
try {
//springboot中有个@Lookup注解 ,xml配置中叫做lookup-method
//主要作用是将A类中a方法的返回值,替换成指定的返回值,a方法可以是一个抽象方法
//这里就是将这些需要重写的方法,标记出来
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//在创建bean实例化之前,让bean的后处理器尝试返回一个代替对象(这里的代替对象,不一定是代理对象,可能只是一个被置换的对象)
//步骤10
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//在步骤10中如果返回了代替对象,就直接返回结果
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//如果步骤10中没有返回代替对象,就会在这里走向正常的创建bean对象的方法
//步骤12
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
步骤10:尝试让bean后处理器返回代理对象
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//beforeInstantiationResolved判断条件,判断在实例化之前后处理器是否需要启动后处理器
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//bean定制不是合成定义对象 && 有可实例化的bean后处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//确定bean定义中的目标类型(targetType)
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//在实例化之前调用bean的后处理器
//步骤11
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//在实例化之后调用bean的后处理器
//与applyBeanPostProcessorsBeforeInstantiation方法几乎一样 不再详细分析
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
步骤11:在实例化之前调用bean的后处理器
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//获取所有的后处理器,循环处理
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断后处理器是否实现了InstantiationAwareBeanPostProcessor接口
//InstantiationAwareBeanPostProcessor接口,会实例化对象的后处理器
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//强制类型转换
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//调用后处理器的“实例化之前的执行”的方法
//后处理器中有2个方法,一个前置方法“postProcessBeforeInitialization”,一个后置方法“postProcessAfterInitialization”
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
步骤12:创建bean对象
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//用来存放实例化的bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//单例对象需要在未完成的FactoryBean实例的缓存中将其删除
//factoryBeanInstanceCache中存放FactoryBean的Name与bean的包装器(beanWrapper)的映射关系
//目的是为更新这个单例对象的时候,不会被获取到旧的对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建一个新的bean实例,返回出来的是一个bean的包装对象(beanWrapper)
//步骤13
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//从beanWrapper中获取bean的实例对象
final Object bean = instanceWrapper.getWrappedInstance();
//获取bean的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
//NullBean.class用来代替null,用来表示空bean
if (beanType != NullBean.class) {
//指定解析的目标类型(targetType)
mbd.resolvedTargetType = beanType;
}
// 允许后处理器修改合并的bean定义
//上锁 后处理器的锁对象
synchronized (mbd.postProcessingLock) {
//判断是否运行过MergedBeanDefinitionPostProcessors类型的后处理器
if (!mbd.postProcessed) {
try {
//MergedBeanDefinitionPostProcessors类型的后处理器挺重要的
//其中有个AutowiredAnnotationBeanPostProcessor类,用于对标有@Value和@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;
}
}
// 判断是否需要将尚未完全处理结束的bean提前暴露出去,用于解决循环依赖
//bean是单例的 && 允许循环依赖 && 单例的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");
}
//getEarlyBeanReference方法,返回这个对象的单例工厂
//addSingletonFactory方法,调整bean对象在容器中的状态
//如果singletonObjectsr容器中包含这个bean对象那么就进行以下操作
//1、将对象存入singletonFactories容器中
//2、从earlySingletonObjects容器中移除
//3、添加到registeredSingletons中
//这几个容器具体的作用已经在上文中用红色字说明过了
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 暴露出来的bean对象
Object exposedObject = bean;
try {
//属性值注入,将bean定义中的属性值(在Spring配置文件中配置的属性值)赋值到beanWrapper的bean实例对象中
populateBean(beanName, mbd, instanceWrapper);
//初始化给定的bean实例,调用工厂的回调、init方法和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);
}
}
//提前暴露bean实例
if (earlySingletonExposure) {
//获取到bean实例对象
Object earlySingletonReference = getSingleton(beanName, false);
//可以获取到bean实例对象
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
//在循环引用的情况下不允许未经过包装的bean进行注入 && 给定的beanName已经注册了需要依赖的bean
//如果这个类拒绝发生循环依赖,就会进入这里判断是否存在循环依赖
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//获取依赖的bean对象
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//如果给定的依赖的bean,
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
//添加到实际依赖的集合中
actualDependentBeans.add(dependentBean);
}
}
//如果这个集合不为空,证明出现了循环依赖的情况
if (!actualDependentBeans.isEmpty()) {
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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 将bean注册到销毁的容器中,当关闭SpringBoot的时候,SpringBoot会根据注册这个销毁的容器中的信息,逐一的将bean销毁掉,完成优雅的关闭
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
//返回bean的实例对象
return exposedObject;
}
步骤13:创建bean的实例化
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//获取bean的class类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//能找到bean的class类型 && 类的修饰符不是public && 不允许非公共访问(不允许允许访问这个类的非公共构造函数和方法)
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//Supplier类型是java8中的新特性,lamdba4大接口之一,如果不太懂的小伙伴可以这样理解
//supplier代表个方法(或者是一段逻辑),这个方法没有参数,并且会有一个返回值
//正常情况下这里的instanceSupplier == null
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
//直接通过instanceSupplier的逻辑创建bean,正常走不到这里
return obtainFromSupplier(instanceSupplier, beanName);
}
//判断是否存在工厂方法,一般通过工厂bean加载,这里就不会为null
if (mbd.getFactoryMethodName() != null) {
//通过工工厂方法进行bean的实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
//上锁防止被一个单例bean被多个地方同时实例化
synchronized (mbd.constructorArgumentLock) {
//判断是否解析过构造方法或者工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//修改标识符的状态
resolved = true;
//是否需要自动识别构造函数的参数
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认的构造函数
return instantiateBean(beanName, mbd);
}
}
// 根据构造函数的参数,解析、确定需要使用哪个构造函数进行初始化,返回用于初始化的构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 如果用户指定了首选构造器,就是用首选构造器初始化
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//使用默认构造器,无参构造器
return instantiateBean(beanName, mbd);
}
不管有参还是无参,最后都是默认通过cglib使用反射的手段进行实例化,SpringBoot是默认使用cglib,早期的spring是通过jdk的反射直接实例化的,然后会被包装成beanWrapper,最后再返回出来