Spring源码(十四)doGetBean方法

doGetBean

Spring源码(十四)doGetBean方法


getSingleton方法,每次创建bean的时候,都需要去容器中查找。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		// 从单例对象缓存中获取beanName对应的单例对象
		Object singletonObject = this.singletonObjects.get(beanName);
		// 如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
			// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
			singletonObject = this.earlySingletonObjects.get(beanName);
			// 如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
			if (singletonObject == null && allowEarlyReference) {
				// 如果为空,则锁定全局变量并进行处理
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							// 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								// 如果存在单例对象工厂,则通过工厂创建一个单例对象
								singletonObject = singletonFactory.getObject();
								// 记录在缓存中,二级缓存和三级缓存的对象不能同时存在
								this.earlySingletonObjects.put(beanName, singletonObject);
								// 从三级缓存中移除
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

这里每次都会从一级缓存中查找,为空,那么就要创建了,getSingleton这个方法后面讲。

继续,if是用来,如果一个bean对象实现了FactoryBean接口,那么在整个spring的生命周期中会创建两个对象,第一个表示实现了FactoryBean接口的子类,由spring帮我们创建,第二个会调用getObject方法返回一个对象,此对象创建的过程由getObjectForBeanInstance方法调用实现的。
这里就是判断factoryBean有没有执行,如果没执行跳过,如果执行了,那么获取到另外一个对象。

继续往下,

			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况,那么直接抛出异常。

接下来,获取我们的父容器,再判断。

			if (!typeCheckOnly) {
				// 为beanName标记为已经创建(或将要创建)
				markBeanAsCreated(beanName);
			}

如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录。用set集合的方式添加将要创建的bean名称。这里会清除rootBeanDefinition,为了防止有一些元数据变化。

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

这个方法是从mergedBeanDefinitions集合中拿出一个,实际上此集合在BFPP的getName里面定义好的。如果从集合中找不到,那么重新进行获取。

checkMergedBeanDefinition(mbd, beanName, args);

检查MergedBeanDefinition。

然后判断是否有depend-on这个属性,如果有,那么把depend-on这个bean先创建了。

				if (mbd.isSingleton()) {
					// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除
							// 接收到该Bean临时引用的任何Bean
							// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
							destroySingleton(beanName);
							// 重新抛出ex
							throw ex;
						}
					});

上面的getSigleton最后一个参数是objectFactory。
objectFactory是一个函数式接口,当调用其中getObject方法的时候,才会将实际传递的匿名内部类中的实现逻辑来进行执行。
先看下getSingleton方法的重载。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		// 如果beanName为null,抛出异常
		Assert.notNull(beanName, "Bean name must not be null");
		// 使用单例对象的高速缓存Map作为锁,保证线程同步
		synchronized (this.singletonObjects) {
			// 从单例对象的高速缓存Map中获取beanName对应的单例对象
			Object singletonObject = this.singletonObjects.get(beanName);
			// 如果单例对象获取不到
			if (singletonObject == null) {
				// 如果当前在destorySingletons中
				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 + "'");
				}
				// 创建单例之前的回调,默认实现将单例注册为当前正在创建中
				beforeSingletonCreation(beanName);
				// 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
				boolean newSingleton = false;
				// 有抑制异常记录标记,没有时为true,否则为false
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				// 如果没有抑制异常记录
				if (recordSuppressedExceptions) {
					// 对抑制的异常列表进行实例化(LinkedHashSet)
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 从单例工厂中获取对象
					singletonObject = singletonFactory.getObject();
					// 生成了新的单例对象的标记为true,表示生成了新的单例对象
					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.
					// 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态
					// 尝试从单例对象的高速缓存Map中获取beanName的单例对象
					singletonObject = this.singletonObjects.get(beanName);
					// 如果获取失败,抛出异常
					if (singletonObject == null) {
						throw ex;
					}
				}
				// 捕捉Bean创建异常
				catch (BeanCreationException ex) {
					// 如果没有抑制异常记录
					if (recordSuppressedExceptions) {
						// 遍历抑制的异常列表
						for (Exception suppressedException : this.suppressedExceptions) {
							// 将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
							ex.addRelatedCause(suppressedException);
						}
					}
					// 抛出异常
					throw ex;
				}
				finally {
					// 如果没有抑制异常记录
					if (recordSuppressedExceptions) {
						// 将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
						// 可防止异常信息的混乱
						this.suppressedExceptions = null;
					}
					// 创建单例后的回调,默认实现将单例标记为不在创建中
					afterSingletonCreation(beanName);
				}
				// 生成了新的单例对象
				if (newSingleton) {
					// 将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
					addSingleton(beanName, singletonObject);
				}
			}
			// 返回该单例对象
			return singletonObject;
		}
	}

以时间来描述整个bean的生命周期的话。
在这里插入图片描述
beforeSingletonCreation(beanName);方法,添加了当前bean对象在正在创建的过程中。根据这个标识,这个集合,去做什么事情了。

singletonObject = singletonFactory.getObject();

执行到这步,核心点。这里就调用了ObjectFactory,(objectFactory是一个函数式接口,当调用其中dgetObject方法的时候,才会将实际传递的匿名内部类中的实现逻辑来进行执行。),然后就回到了匿名内部类进行执行。
然后执行createBean了,这个是真正创建的流程。

总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值