Spring的循环引用

Spring的循环引用

实力有限,如有勘误,请指出

1.Spring中的三级缓存

在创建Bean的过程中,Spring 会先去单例缓存中查找Bean是否已经被创建。

	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//从单例缓存(一级缓存)如果有就返回
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果不存在并且该Bean正在创建
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				//查找二级缓存
				singletonObject = this.earlySingletonObjects.get(beanName);

				//二级缓存找不到 并且是允许循环引用的
				if (singletonObject == null && allowEarlyReference) {
					//ObjectFactory
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						//如果有存入到二级缓存当中。
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}
  1. 第一级缓存singletonObjects 存储的是单例的完整的Bean对象。
  2. 第二级存储的是婴儿Bean就是比如属性没有赋值。
  3. 第三级缓存也是类似

一个先Bean从初始化到未给属性赋值的时候,先放到三级缓存当中。
AbstracAutowriedCapableBeanFactory#doCreateBean 方法中

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");
			}
			//放到三级缓存当中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}


然后需要对属性设置populateBean:

protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//非简单属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

		//遍历
		for (String propertyName : propertyNames) {
			//如果是一个Bean
			if (containsBean(propertyName)) {
				//初始化Bean
				Object bean = getBean(propertyName);
				//属性名--> 属性值
				pvs.add(propertyName, bean);
				//属性依赖注入
				registerDependentBean(propertyName, beanName);
				if (logger.isTraceEnabled()) {
					logger.trace("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

举例:UserService 依赖 OrderService ,OrdeService 依赖UserService

UserService 先创建,初始化之后放入三级缓存,需要属性注入的时候发现存在依赖对象OrderService,那就先(getBean 方法 )创建OrderService,OrderService 先把自己放入三级缓存,属性注入的时候发现依赖UserService,就去GetBean创建,先查缓存中UserService,它在三级缓存中,把它拿到放入二级缓存,设置属性,然后OrderService 就到了一级缓存,整个递归结束返回。UserService拿到OrderService,把自己放入到一级缓存。

什么时候放入一级缓存呢?

				// 如果是单例的Bean对象
				if (mbd.isSingleton()) {
					//创建完成之后放入一级缓存
					sharedInstance = getSingleton(beanName, () -> {
						try {
							/**
							 * 创建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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

这个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 + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					/** <1> 如果在二级缓存中找到了 那就是新的单例对象 */
					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) {
					/**
					 * 
					 * <2> 放入到缓存当中
					 */
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值