Spring源码解析(一)循环依赖

Spring源码解析(一)循环依赖

循环依赖

​ 本章将通过源码的方式去解释spring是如何解决循环依赖的,可以直接找一个springboot项目或者spring项目,全局搜索即可跟随学习。

  • 先做个准备工作,全局搜索(按三下shift)DefaultSingletonBeanRegistry这个类

在这里插入图片描述

整体思路

spring解决循环依赖问题的主要思路:三级缓存

  • Map<String, Object> singletonObjects:一级缓存
  • Map<String, Object> earlySingletonObjects:二级缓存
  • Map<String, ObjectFactory<?>> singletonFactories:三级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

set和构造方法

​ spring初始化属性值的方法:set和构造方法

  • set方法
  • 构造方法(初始化)
  • 工厂方法

​ 这里只需要说set和构造方法:

  • 解决循环依赖的方法:set方法可以解决循环依赖,构造方法不能解决循环依赖。
  • 解决方法:
    • set方法:先完成了对象的创建,之后才通过set方法设置属性。
    • 构造方法:创建出对象之后,立即给对象一个属性值
  • 解决循环依赖的关键:把实例化和初始化分开,先给earlyBean(未设置值)的Bean待用(提前暴露对象),A依赖B,B依赖A,只要有一个依赖一个不完整的Bean就能把环打破,解决循环依赖。

结构图

  • 先实例化A,但并未放入实例B,此时有两种选择
    • 将实例A放入spring缓存中,供已经初始化完毕的实例B使用(此时A为半成品)
    • 初始化A,此时设置B的属性值,此时又面对两种选择:
      • spring的缓存中有实例B,则直接赋值使用。
      • spring的缓存中没有实例B,创建对象B,实例化B但不设置属性值(不注入A),将半成品的B给到A去使用。

​ 总结:getBean—>doGetBean—>createBean—>doCreateBean
在这里插入图片描述

查看源码

  • 回到先前的DefaultSingletonBeanRegistry类,先把之前介绍的三个map记住。
    • Map<String, Object> singletonObjects:一级缓存
    • Map<String, Object> earlySingletonObjects:二级缓存
    • Map<String, ObjectFactory<?>> singletonFactories:三级缓存

​ 再记住一点,过程为:getBean—>doGetBean—>createBean—>doCreateBean

  • 跟随着上面的过程,先找到getBean这个方法,直接调用了DoGetBean方法

    • name:bean的名字
	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
  • 进入doGet方法:从三级缓存中获取bean,接下来部分主要是一个大if,解释清楚这个if就好理解了(解决循环依赖的if)
    • 三级缓存中获取到的bean不为空,且传入的创建bean所需参数为空,返回bean(在这个if中,说明已经解决了循环依赖)

      • 判断是否启用了跟踪弄日志

        • 判断当前bean是否处于正在创建过程中
      • 否则,说明创建完成

    • 三级缓存获取的bean为空,说明此时我们可能存在循环依赖中

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		//别名映射
		String beanName = transformedBeanName(name);
		//新建bean对象
        Object bean;
		// Eagerly check singleton cache for manually registered singletons.
        //从一级和二级缓存获取bean,如果没有,则用三级的bean工厂缓存创建,返回bean。(重点!!!)
		Object sharedInstance = getSingleton(beanName);
        //如果bean不为空,且创建bean的参数为空
		if (sharedInstance != null && args == null) {
            //启用了日志跟踪
			if (logger.isTraceEnabled()) {
                //从缓存singletonsCurrentlyInCreation中,获取是否正在创建bean
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
            //获取bean
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
        //三级缓存获取的bean为空,说明此时我们可能存在循环依赖中
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
            
            //判断当前创建的bean,和我们要创建的bean是否同名,同名则抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			// Check if bean definition exists in this factory.
            //获取bean工厂的父类工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
            //父类工厂不为空且缓存中不包含该类
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
                //确定原始名称,将本地定义名解析成规范名称,&+beanName
				String nameToLookup = originalBeanName(name);
                //如果父工厂类,实现了AbstractBeanFactory类
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
                //如果bean创建的参数不为空
				else if (args != null) {
					// Delegation to parent with explicit args.
                    //传入bean的名字和创建所需的参数,使用父类的工厂类获取bean
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
                //需要检索的bean的类型不为空
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
                    //从父类的bean工厂中传入bean的名字和类型进行创建
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
                    //否则,直接传入bean名字创建
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
			//不进行实例检查,并将其标记成已创建
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			//初始化bean的依赖!!涉及递归(重要)
			try {
                //返回该bean的顶级父类
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //判断该父类是否为Abstract(抽象),否则抛出异常
				checkMergedBeanDefinition(mbd, beanName, args);
				// Guarantee initialization of beans that the current bean depends on.
                //返回这个父类bean所有依赖的bean名称
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
                    //遍历获取到的依赖的bean名称
					for (String dep : dependsOn) {
                        //确定是否为该bean所需的依赖
						if (isDependent(beanName, dep)) {
                            //不是则抛出异常
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
                        //为给定的bean注册依赖
						registerDependentBean(dep, beanName);
						try {
                            //递归调用bean,使用的方法是doGetBean,也就是本方法
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
                //初始化父类依赖所需的bean后,就开始创建自己的bean
                //如果范围为单例(单例:每一次调用都是原本的bean,原型:每一次调用都注入新的bean)
				if (mbd.isSingleton()) {
                    //返回给定的对象,如果没有则new一个
					sharedInstance = getSingleton(beanName, () -> {
						try {
                            //创建 bean 实例、填充 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.
                            //如果bean创建出现异常则直接销毁,因为有可能导致循环依赖
							destroySingleton(beanName);
							throw ex;
						}
					});
                    //从缓存中获取已经创建的bean(重要!!)
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                //如果范围为原型(单例:每一次调用都是原本的bean,原型:每一次调用都注入新的bean)
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
                    //原型->创建新的实例,初始化新的bean
					Object prototypeInstance = null;
					try {
                        //创建原型之前的回调。默认实现将原型注册为当前正在创建中。
						beforePrototypeCreation(beanName);
                        //创建bean,同上(同上,重要!)
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
                        //创建完毕后,将其移除正在创建的缓存中
						afterPrototypeCreation(beanName);
					}
                    //获取创建完成的bean(同上,重要!)
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//如果都不是
				else {
                    //获取范围
					String scopeName = mbd.getScope();
                    //保证不为空,也不为null
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
                    //获取bean的范围
					Scope scope = this.scopes.get(scopeName);
                    //再次保证不为空,否则报错
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
                        //由于不属于单例也不属于原型,所以按原型处理(同上)
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}
		
		// Check if required type matches the type of the actual bean instance.
        //检查校验下和原本的bean是否相同
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
  • 先查看getSingleton这个方法:从一级和二级缓存获取bean,如果没有,则用三级的bean工厂缓存创建,返回bean。
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // Quick check for existing instance without full singleton lock
        //先到一级缓存中获取对象
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果一级缓存为空并且没有正在创建的bean(正在创建的bean也有一个map保存)
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            //从二级缓存中获取bean
            singletonObject = this.earlySingletonObjects.get(beanName);
            //如果bean为空,并且允许早起创建引用
            if (singletonObject == null && allowEarlyReference) {
                //上锁
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    //重新获取一次一级缓存的bean确保不会重复创建
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        //获取二级缓存
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            //从三级缓存中获取(bean工厂)
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                            //如果bean工厂中不为空
                            if (singletonFactory != null) {
                                //从bean工厂中获取对象
                                singletonObject = singletonFactory.getObject();
                                //将bean塞入二级缓存
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                //从三级缓存中删除bean工厂
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }
  • 再来看一下重载的方法
    • suppressedExceptions用于获取抑制的异常
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        //保证beanName不为空
        Assert.notNull(beanName, "Bean name must not be null");
        //锁住第一层缓存
        synchronized (this.singletonObjects) {
            //获取对应的bean
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //如果bean为空,并且在执行销毁(默认false),则报错
                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 + "'");
                }
                //如果不在排除的bean当中,也不在正在生成的bean当中
                beforeSingletonCreation(beanName);
                //一级缓存获取bean失败
                boolean newSingleton = false;
                //suppressedExceptions用于获取抑制的异常,这里表示没有发生过异常是true,否则为true
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                //如果没有发生异常则创建新的set
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                //从bean工厂中获取bean,可能bean工厂没有,就会被捕获
                    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 {
                    //没有异常,就把获取异常的类设置为null
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
  • 来查看一下getObjectForBeanInstance方法:
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
		// Don't let calling code try to dereference the factory if the bean isn't a factory.
        //如果是工厂引用(name以&开头)
		if (BeanFactoryUtils.isFactoryDereference(name)) {
            //判断不为空
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
            //如果不是工厂类,则抛出异常
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
            //同事满足mdb不为空和FactoryBean子类,则说明是工厂类
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
            //返回该类
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
        
       	//上面说白了,就是把工厂的引用类筛选出去了,下面仅剩下:普通类和工厂类。
        //普通类:直接返回。工厂类:就用工厂创建出我们需要的实体。
        
		if (!(beanInstance instanceof FactoryBean)) {
        //如果不是工厂类,则直接返回
			return beanInstance;
		}
        //初始化一个类
		Object object = null;
		if (mbd != null) {
            //判定当前类为工厂类
			mbd.isFactoryBean = true;
		}
		else {
            //从bean工厂单例对象缓存中,获取指定的bean
			object = getCachedObjectForFactoryBean(beanName);
		}
        //如果获取到的bean为空,说明缓存中没有或为bean工厂
		if (object == null) {
			// Return bean instance from factory.
            //强转为bean工厂
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			//mdb为空,且存在于bean工厂的缓存中
            if (mbd == null && containsBeanDefinition(beanName)) {
                //获取rootbeanfine
				mbd = getMergedLocalBeanDefinition(beanName);
			}
            //如果 mbd不为空,且mbd是合成的,则为true
			boolean synthetic = (mbd != null && mbd.isSynthetic());
            //从bean工厂获取指定的bean
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
        //返回bean
		return object;
	}

​ 至此,spring循环依赖的源码看完了,后续还有很多spring的源码扩展和部分相关知识,我会再分享到平台上以供一起学习。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值