SpringBoot源码初学者(四):单例bean实例化

  • Post author:
  • Post category:其他


ps:bean初始化相关的内容实在太多,不得已只好将其分成上下两篇来讲



一、finishBeanFactoryInitialization方法定位

这里所说的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实例化理解会很有帮助



二、bean实例化解析



1、前期准备

步骤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));
}



2、bean对象的获取

步骤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的名称



3、创建bean对象

步骤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,最后再返回出来



版权声明:本文为qq_34886352原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。