Spring解决循环依赖-源码分析

18 篇文章 0 订阅

Spring容器初始化最后,完成对扫描出的BeanDefinition初始化,并存放到map容器中。

首先从doGetBean开始分析, 此时容器已初始化完成, 开始执行bean的初始化

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
	...
	Object bean;

	// 此处从缓存中获取对象, 如果对象已经被初始化, 则直接返回; 获取对象优先顺序:
	// 1.singletonsCurrentlyInCreation存储当前正在创建的bean
	// 2.earlySingletonObjects存储bean的早期依赖 已被实例化 但属性没有赋值的bean
	// 3.singletonFactories存储创建bean的工厂 在此可完成创建代理对象
	// 如果需要从工厂创建bean, 在创建完成后, 添加到earlySingletonObjects, 并且从singletonFactories中移除
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		...
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	} else {
		try {
			// Create bean instance.
			if (mbd.isSingleton()) {
				// 此处添加了一个匿名类对象,待会儿会调用
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					@Override
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							...
						}
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			...				
		}
		catch (BeansException ex) {
			...
		}
	}
	...
	return (T) bean;
}

第一个getSingleton,从缓存中获取,第一次获取为null

// 从缓存中获取对象, 如果对象已经被初始化, 则直接返回
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
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<?> singletonFactory = this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
					singletonObject = singletonFactory.getObject(); // 三级缓存 Factory 可能需要代理
					this.earlySingletonObjects.put(beanName, singletonObject);
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

第二个getSingleton

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	// 判断是否为null
	Assert.notNull(beanName, "'beanName' must not be null");
	synchronized (this.singletonObjects) {
		// 首先从单例对象Map中获取bean
		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 + "'");
			}
			// 判断对象是否存在于singletonsCurrentlyInCreation, 如是报异常
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<Exception>();
			}
			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;
				}
				// 从当前创建对象池Set中移除当前beanName
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				// 执行了以下操作: 标记对象已创建完成
				// singletonObjects.put   添加到一级缓存张
				// singletonFactories.remove
				// earlySingletonObjects.remove
				// registeredSingletons.add
				addSingleton(beanName, singletonObject);
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}
}

singletonFactory.getObject()代码解析

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
	...
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	...
	return beanInstance;
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
		throws BeanCreationException {
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 通过构造方法实例化bean,并存放到wrapper包装对象中  ----------完成实例化
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance(); // 真实对象
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	...
	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	// 判断db是否为单例, 并且容器是否允许循环引用, 并且对象不在当前创建池中
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		// 执行一下步骤
		// singletonFactories.put  添加到一级缓存中
		// earlySingletonObjects.remove
		// registeredSingletons.add
		// 这里也是构造了一个匿名类对象 在
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				// 这个方法在三级缓存处, 从第三级向第二级转存的时候调用
				// 获取对象的早期依赖, 此时对象已被实例化, 但是属性未被赋值
				// 方法内通过beanPostProcessor可以完成代理
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// 为对象(包含早期依赖对象)属性赋值
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			// 此方法内对Spring部分扩展功能进行回调
			// BeanNameAware / BeanFactoryAware / BeanPostProcessor.postProcessBeforeInitialization / InitializingBean.afterPropertiesSet / initMethod / BeanPostProcessor.postProcessAfterInitialization
			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) {
		// 再次获取对象, 此时可以从早期依赖对象池中获取
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				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 " +
							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

此方法可以完成对对象的代理,如果使用了AOP,通过AnnotationAwareAspectJAutoProxyCreator父类的getEarlyBeanReference方法产生代理

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { // 包含不限于AnnotationAwareAspectJAutoProxyCreator
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
	}
	return exposedObject;
}

// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
public Object getEarlyBeanReference(Object bean, String beanName) {
	Object cacheKey = getCacheKey(bean.getClass(), beanName);
	if (!this.earlyProxyReferences.contains(cacheKey)) {
		this.earlyProxyReferences.add(cacheKey);
	}
	return wrapIfNecessary(bean, beanName, cacheKey);
}

// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	...
	// Create proxy if we have advice.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 生成代理对象
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

只有一级缓存
Map中包含了初始化完毕的bean和未完成的bean, 当有线程获取bean时, 会有问题

只有二级缓存
一个Map存放了初始化完成的bean, 一个存放了未完成的bean, 但是无法解决aop下需要代理的bean

两级缓存
在需要代理的情况下, 一级缓存就要放入代理对象, 二级缓存存放初始化完成的对象. 但是无法解决循环依赖的问题, 因为一级中放入的代理对象如果依赖的当前对象, 再次注入当前对象的代理对象时, 会产生新的代理对象, 会导致两个对象不一致, 解决不了循环依赖

前置条件
A->B B->A Spring先装载A, 后装载B

结论
如果A为prototype, 无论B是否为单例, 循环依赖都会出错, 因为在初始化B时, 发现依赖A, 会注入一个新的A, 出现死循环;
如果A为singleton, 无论B是否为单例, 循环依赖都没有问题, 即便B不是单例, B实例化时, 注入已经实例化的A, 初始化仍然能够完成.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值