Spring的createBean()流程源码解析(持续更新中)

承接上篇的getSingleton()方法,缓存中不存在对应bean的实例,开始调用createBean方法创建对象

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		//当前bean的定义信息
		RootBeanDefinition mbdToUse = mbd;

		//从bean的定义信息中获取到一个指定的类的class引用
		//根据设置的class属性或者根据className来解决class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			//将上步骤中获取到的指定名称的bean的class引用放入到bean的定义信息中
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.准备方法覆盖
		/**
		 * 对override属性进行标记和验证,这里有所不同的是Spring的配置里面根本
		 * 没有override-method之类的配置,但是在spring配置中存在lookup-method
		 * 和replace-method,这两个配置会被统一存放在beanDefinition中的methodOverrides
		 * 属性里,这个方法也就是对这两个配置做操作。
		 */
		try {
			//对override属性进行标记和验证
			/**
			 * 在Spring配置中存在lookup-method和replace-method,这两个配置的加载
			 * 其实就是将配置统一存放在beanDefinition中的methodOverrides属性中.
			 * 这个函数的操作其实就是这两个配置的。
			 */
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			//给beanPostProcessors一个机会来返回代理来替代真正的实例
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//实际创建指定的bean。
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
//真正开始创建bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		//实例化bean。
		//BeanWrapper是对Bean的包装
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//将要创建的对象---从未完成的FactoryBean实例的缓存中移除:FactoryBean--->BeanWrapper
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//根据beanName、bean的定义信息、args创建一个新的实例对象
			//根据值得bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简化初始化
			/**
			 *  如果存在工厂方法则使用工厂方法进行初始化。
			 *  一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
			 *  如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化。
			 */
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//获取BeanWrapper所包装的bean实例。
		Object bean = instanceWrapper.getWrappedInstance();
		//获取BeanWrapper所包装的bean实例的类型
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 允许后处理器修改合并bean的定义。
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//执行后处理,合并指定bean的定义信息。
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				//标记已经执行了后处理,合并指定bean的定义信息。
				mbd.postProcessed = true;
			}
		}
		// Eagerly cache缓存单例以能够解析循环引用

		// 判断是否曝光早期的单例对象
		/**
		 * 第一个判断:判断当前bean的定义是否为单例
		 * 第二个判断:判断是否自动尝试解析bean之间的循环引用
		 * 第三个判断:判断指定的单例bean当前是否在创建中
		 */
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			//为true,则需要曝光早期的单例对象
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//这里创建了一个匿名的ObjectFactory 实现类, 他是一个工厂, 可以用来获取对象
			//addSingletonFactory中, 将这个工厂放到 singletonFactories 中去了. singletonFactories 是spring的三级缓存
			//这里将对象信息和该对象的工厂,放入到三级缓存中,下次获取时直接获取到指定工厂来创建对象。
			//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
			//为避免后期的循环依赖,可以在bean初始化完成前,将创建实例的objectFactory加入工厂中
			//其中我们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做处理
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// exposedObject:暴露的对象
		Object exposedObject = bean;
		try {
			//为上一步创建的bean填充属性,
			//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
			//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
			//初始化给定的bean实例,应用工厂回调以及初始化方法和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) {
			//从缓存中获取对应的bean对象(allowEarlyReference为false时,相当于只在一、二级缓存中查找指定对象)
			Object earlySingletonReference = getSingleton(beanName, false);
			//earlySingletonReference 只有在检测到有循环依赖的情况下才不会为空
			if (earlySingletonReference != null) {
				//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
				//如果exposedObject 没有在初始化方法中被改变,也就是没有被增强
				if (exposedObject == bean) {
					//当前实例化的Bean初始化完成
					exposedObject = earlySingletonReference;
				}
				//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					//获取当前Bean所依赖的其他Bean
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						//对依赖Bean进行类型检查
						//检测依赖
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					//因为bean创建后其所依赖的bean一定是已经创建的,actualDependentBeans不为空则表示当前bean
					//创建后其依赖的bean没有全部创建完成,也就是说存在循环依赖。

					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 " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		//注册完成依赖注入的Bean
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值