源码来看Spring三重缓存

本文详细解释了Spring框架中创建bean的过程,包括preInstantiateSingletons方法、singletonFactory.getObject的调用链,以及属性注入和缓存机制。重点描述了单例bean的创建、工厂bean的处理和依赖注入的步骤。
摘要由CSDN通过智能技术生成
Spring创建bean的流程如图

beanFactory.preInstantiateSingletons();从这个函数开始创建单例bean对象

for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						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) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}

 从这边开始getbean,去尝试获取bean对象。

getBean调用doGetBean方法

 doGetBean方法根据不同的作用域来决定怎么调用createBean方法。getSingleton传递了一个lamda表达式用于实现ObjectFactory的getObject方法。

当调用getObject方法后会调用传递进来的lamda表达式,也就是调用了createBean方法

 createBean调用了doCreateBean方法

doCreateBean调用了createBeanInstance方法来创建实例 ,通过不同的构造策略来实例化,比如说构造器注入,或者是通过反射创建对象等等。

拿到该实例bean后,在第三重缓存SingletonFactory中放入(beanName,lamda)的元素,接着去进行属性注入populateBean。

 会根据你选择的autowired方式来进行属性注入

 通过containsBean,去一重缓存找,找不到去BeanDefinition中找,都找不到说明不存在报错

 然后调用getBean方法来进行获取bean注入属性。此时会访问三重缓存,询问有没有这个bean(按顺序)

此时的三重缓存如图

并没有和B相关的元素。所以要继续创建B对象。此时已经有了半成品A,但是游离在三重缓存外。

此时B也要经过上面CreateBean,doCreateBean,createBeanInstance,populateBean的流程。到了属性注入时又去getBean寻找A。

此时的BeanFactory如图

此时B再去三重缓存中get A已经可以在三重缓存中拿到A的lamda表达式了

同样的这个lamda表达式调用了getObject

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

实际调用了这个函数把半成品beanA返回了回去。调用完getObject后三重缓存删除A对应的lamda表达式并把半成品A放入二级缓存。

此时的BeanFactory如图

getBean返回了半成品的A,调用applyPropertyValues,获得了完整的B对象。此时getbean方法会返回B对象给A,A也变成了完成品。其实就是A在调用singletonFactory.getObject();去创建单例对象,结束后就放入了一重缓存。

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 + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();
					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.
					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;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}

然后通过这个方法注册进一重缓存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值