Spring源码-循环依赖

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

	/** Cache of singleton objects: bean name to bean instance. */
    // 一级缓存
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
    // 三级缓存
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
    // 二级缓存
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

流程

这里已A、B对象作为例子,A依赖B,B依赖A

部分关键源码解析

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        // 所有的beanDefinition名字的集合
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
        // 触发所有非懒加载的单例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 {
                    // 普通的Bean,通过beanName获取实例
					getBean(beanName);
				}
			}
		}

	...
	}

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

	@Override
	public Object getBean(String name) throws BeansException {
        // 调用doGetBean
		return doGetBean(name, null, null, false);
	}

 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
        // 将名字做个转化(因为可能存在Bean实现FactoryBean接口的可能)
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// Eagerly check singleton cache for manually registered singletons.
        // 从缓存中获取bean,顺序为一级->二级->三级
		Object sharedInstance = getSingleton(beanName);
		

		else {
        ...
				// Create bean instance.
                // 创建bean实例
				if (mbd.isSingleton()) {
                    // 如果已经注册,则返回以beanName的实例对象,否则调用singleFactory的getObject方法进行创建(实际调用的是createBean方法)
					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;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				...
		}

		return adaptBeanInstance(name, beanInstance, requiredType);
	}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
        ...
		try {
            // 调用doCreateBean实际进行bean的创建
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
        ...
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    ...
    if (instanceWrapper == null) {
            // 通过反射创建Bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
    ...
// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		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");
			}
            // 将lambda表达式放入三级缓存,为了避免后期循环依赖
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
    ...
    // Initialize the bean instance.
		Object exposedObject = bean;
		try {
            // 属性赋值(若发现有循环依赖,则会递归调用getBean方法)
			populateBean(beanName, mbd, instanceWrapper);
            // 执行初始化逻辑
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
}

 在执行初始化逻辑initializeBean后,会调用org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton方法

	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
            // 将成品对象放到一级缓存,移除二级、三级缓存
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

值得注意的是,在doCreateBean方法中有一行代码是这样的

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

这个方法的作用是将lambda表达式放到三级缓存中,在属性赋值时若发现有依赖其他对象,则重新调用doGetBean方法时会调用getSingleton方法从缓存中取,具体源码如下

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
        // 现从一级缓存中取,取不到再从二级缓存中取,取不到在从三级缓存中取
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			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) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

取值的优先级为一级->二级->三级,在三级缓存中进行取值的时候,调用了singletonFactory.getObject()方法,该方法真正的实现逻辑为getEarlyBeanReference方法。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference

	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
        // 判断是否为应用程序自己本身定义的且是否有beanPostProcessor后置处理器,
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
                // 提前暴露经过后置处理器增强的对象
				exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
		return exposedObject;
	}

如果需要创建代理对象,那么对外暴露的对象是代理对象而不是原始对象,但是创建代理对象是在初始化过程的beanPostProcessor中去进行的;因此可能在属性赋值的过程中需要引用的就是代理对象,那么只有在对象第一次对外暴露的时候就需要判断是否需要代理对象,如果需要就返回代理否则就返回原始对象,具体的的源码就如上图。 

构造函数的循环依赖

无法解决。因为构造函数是在实例化过程中,此时还没有实例放入三级缓存中,缓存无法命中,所以无法解决构造器循环依赖。

在利用构造函数互相注入依赖时,在createBeanInstance中会调用autowireConstructor->autowireConstructor->createArgumentArray->resolveAutowiredArgument->this.beanFactory.resolveDependency

resolveDependency最终会重新调用getBean方法去创建需要依赖的bean。但无参构造函数是在bean实例化完后才放入到三级缓存,而通过有参构造函数注入则提前了,此时三级缓存中没有任何数据,因此会出现循环依赖的报错问题。

多例下的循环依赖

无法解决。多例作用域的bean不是在IOC容器启动的时候开始bean的生命周期的,而是在用到的时候调用getBean方法进行生命周期的流程。每调用一次getBean都会重新生成一个新的对象。从源码中可以看出只有单例bean才能利用缓存。

暴露早期对象时会判断是否是单例,如果不是单例不会放到三级缓存中

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

        ...
		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
        // 单例且允许循环依赖且当前单例bean正在创建中则加入到三级缓存
		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));
		}

如果是多例并且正在创建会直接抛异常

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

            ...
            // Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值