获取单例bean

前面分析了从缓存中获取bean,那么没有缓存的时候,按照推理,就是应该创建bean了.
Spring中运用了一个重载方法:getSingleton来进行获取的.
分析一下这个方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			// 尝试从缓存中获取单例
			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 + "'");
				}
				// 创建前,把beanName记录下来,记录他的加载状态
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 这个就是FactoryBean的getObject方法获取,
					// 而这个getObject是通过lambada表达式创建的,
					// 下面会分析
					singletonObject = singletonFactory.getObject();
					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;
					}
					// 把beanName的创建记录抹去
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					// 更新三个缓存中的beanName数据
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

其实上面去掉一些判断、异常等操作之后剩余的步骤就是:

  • 从缓存中尝试获取
  • 没有获取到就记录bean当前加载状态
  • 调用FactoryBean的getObject方法进行创建对象
  • 创建完成把bean的当前加载状态去掉
  • 最后把三级缓存重新洗牌

另外说一下singletonObject = singletonFactory.getObject();
这里的getObject()方法的实现是啥呢?那就要看一下这个方法调用的地方传入的ObjectFactory是啥了

getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});

上面其实使用了lambda表达式,因为ObjectFactory是一个函数式接口,所以直接创建了.

() -> {
	try {
		return createBean(beanName, mbd, args);
	}catch (BeansException ex) {
		destroySingleton(beanName);
		throw ex;
	}
}

相当于:

()->{
	getObject(){
		try {
			return createBean(beanName, mbd, args);
		}catch (BeansException ex) {
			destroySingleton(beanName);
			throw ex;
		}
	}
}

这样调用了singletonFactory.getObject();方法之后就相当于调用了createBean(beanName, mbd, args)方法.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值