spring源码阅读(5.1.0)——DefaultSingletonBeanRegistry

目录

 

前言

什么是DefaultSingletonBeanRegistry

代码

属性

登记完全实例化的Bean

添加Bean到singletonFactories

获取Bean

getter与setter函数

用于判断的函数

记录bean与bean之间的关系的函数

注册实现了DisposableBean接口的类

销毁Bean的函数

如何解决setter循环依赖

总结


前言

看源码才知道spring真的是一个大家伙,之前不注重方法,看的稀里糊涂的,这里写一点自己看框架源码的感想,一个框架通常有许多接口定义,继承体系比较复杂,首先需要了解框架源码的组成部分,接口一般定义了整体的功能,根据接口了解实现类的功能,接着查看实现类,spring由三大核心组件,这部分在之后的博客中会总结

 

什么是DefaultSingletonBeanRegistry

类继承图:

DefaultSingletonBeanRegistry的作用:

  1. 存储单例Bean
  2. 存储Bean之间的依赖关系
  3. 存储Bean的包含关系(外部类包含内部类)
  4. Bean所处的状态(正在创建、创建完毕等)
  5. 负责单例Bean的销毁(在其中会看到销毁方法的回调)

这意味着DefaultSingletonBeanRegistry会含有许多数据结构用于存储对象或是关系

 

代码

以下代码来自spring 5.1.0,为了方便讲解,会把类的函数进行切割

直系继承关系:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry 

属性

	/** Cache of singleton objects: bean name to bean instance. */
	//缓存完全实例化的Bean
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
	//缓存未完全实例化的Bean
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
	//缓存具有setter循环依赖的未完全实例化的Bean
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

	/** Set of registered singletons, containing the bean names in registration order. */
	//缓存已经实例化的bean的名称,按注册顺序排序beanname
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	/** Names of beans that are currently in creation. */
	//目前正在创建的Bean的名称(构造函数依赖于其他未初始化的Bean)
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** Names of beans currently excluded from in creation checks. */
	//可以免除创建状态(即是否检查有无完全初始化)检查的bean的名称,大概是用于存储非单例Bean的名字,inCreationCheckExclusions存在的beanName,可以并发创建。
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** List of suppressed Exceptions, available for associating related causes. */
    //当从ObjectFactory获得对象时出现异常,把suppressedExceptions的异常一并抛出。作用不大。
	@Nullable
	private Set<Exception> suppressedExceptions;

	/** Flag that indicates whether we're currently within destroySingletons. */
	//当前是否处于销毁Bean的状态,若为true,则无法获得Bean
	private boolean singletonsCurrentlyInDestruction = false;

	/** Disposable bean instances: bean name to disposable instance. */
	//所有实现了DisposableBean接口的Bean,在销毁Bean时,会回调该缓存中Bean的destory方法
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

	/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
	//缓存所有外部类与内部类的关系
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

	/** Map between dependent bean names: bean name to Set of dependent bean names. */
	//缓存bean名称和所有依赖于Bean的名称的集合
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
	//bean名称和bean所依赖的所有名称的集合
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

 

登记完全实例化的Bean

   @Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			//确保Bean已经完全初始化(实例化+注入全部依赖)
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			addSingleton(beanName, singletonObject);
		}
	}

	/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>To be called for eager registration of singletons.
	 * @param beanName the name of the bean
	 * @param singletonObject the singleton object
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			//移除singletonFactories、earlySingletonObjects中对应的bean
			//singletonFactories、earlySingletonObjects、singletonObjects三个缓存具有一定缓存意义
			//在之前的属性介绍中已经说明
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			//登记已经完成初始化的Bean
			this.registeredSingletons.add(beanName);
		}
	}

 

添加Bean到singletonFactories

	/**
	 * Add the given singleton factory for building the specified singleton
	 * if necessary.
	 * <p>To be called for eager registration of singletons, e.g. to be able to
	 * resolve circular references.
	 * @param beanName the name of the bean
	 * @param singletonFactory the factory for the singleton object
	 */
	 
	 //将未完全实例化的Bean(有些依赖未注入)封装成ObjectFactory类型后
	 //存储到singletonFactories缓存中
	 //目的:为了解决setter循环依赖(接下来会解析)
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
            //确保bean未完全初始化
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

 

获取Bean

	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

	/**
	 * Return the (raw) singleton object registered under the given name.
	 * <p>Checks already instantiated singletons and also allows for an early
	 * reference to a currently created singleton (resolving a circular reference).
	 * @param beanName the name of the bean to look for
	 * @param allowEarlyReference whether early references should be created or not
	 * @return the registered singleton object, or {@code null} if none found
	 */
	@Nullable
	/*
	*这个函数一般用于获得依赖Bean或是完全初始化的Bean,按以下顺序进行获取
	*1、从singletonObjects缓存中获取,意味着依赖Bean已经完全初始化(实例化+注入全部依赖)
	*2、从earlySingletonObjects缓存中获取,意味着依赖Bean出现了setter循环依赖,这里获得的是引用
	*3、从singletonFactories缓存中获取,意味着依赖Bean也还没有完全初始化,这里获得的是引用
	*/
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		//isSingletonCurrentlyInCreation函数用于确保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();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

	/**
	 * Return whether the specified singleton bean is currently in creation
	 * (within the entire factory).
	 * @param beanName the name of the bean
	 */
	 //当前是否处于Bean创建状态
	public boolean isSingletonCurrentlyInCreation(String beanName) {
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}
	
	/**
	 * Callback before singleton creation.
	 * <p>The default implementation register the singleton as currently in creation.
	 * @param beanName the name of the singleton about to be created
	 * @see #isSingletonCurrentlyInCreation
	 * 判断Bean是否处于初始化阶段,如果Bean已经处于初始化阶段,则抛出异常,这个函数用于确保单例唯一,否则返回
	 */	 
	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}
	
	/**
	 * Callback after singleton creation.
	 * <p>The default implementation marks the singleton as not in creation anymore.
	 * @param beanName the name of the singleton that has been created
	 * @see #isSingletonCurrentlyInCreation
	 * 表明单例Bean初始化完毕
	 */
	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}
	
	/**
	 * Return the (raw) singleton object registered under the given name,
	 * creating and registering a new one if none registered yet.
	 * @param beanName the name of the bean
	 * @param singletonFactory the ObjectFactory to lazily create the singleton
	 * with, if necessary
	 * @return the registered singleton object
	 * 这个函数直接从ObjectFactory获得Bean,直接存储到singletonObjects缓存中,用于创建单例Bean
	 */
	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) {
				//当前是否处于Bean销毁状态,若处于,则抛出异常,此时不能获得Bean
				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是否处于初始化阶段,确保单例唯一
				beforeSingletonCreation(beanName);
				
				
				boolean newSingleton = false;
				
				//从ObjectFactory获取对象失败时需要一并抛出的异常
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//从ObjectFactory中获取对象
					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;
					}
					//实例化完毕单例Bean
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//添加到singletonObjects缓存中
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

 

 

getter与setter函数

	//获得单例bean的名称列表
	@Override
	public String[] getSingletonNames() {
		synchronized (this.singletonObjects) {
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}

    //获得singletonMutex,调用这个函数的地方必须上锁
    public final Object getSingletonMutex() {
		return this.singletonObjects;
	}

	//获得单例bean的个数
	@Override
	public int getSingletonCount() {
		synchronized (this.singletonObjects) {
			return this.registeredSingletons.size();
		}
	}

	//存储可以并发创建的bean的名称
	public void setCurrentlyInCreation(String beanName, boolean inCreation) {
		Assert.notNull(beanName, "Bean name must not be null");
		if (!inCreation) {
			this.inCreationCheckExclusions.add(beanName);
		}
		else {
			this.inCreationCheckExclusions.remove(beanName);
		}
	}

     /**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * @param beanName the name of the bean
	 * @return the array of dependent bean names, or an empty array if none
	 *返回依赖于该Bean的Bean的名字
	 */
	public String[] getDependentBeans(String beanName) {
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
			return new String[0];
		}
		synchronized (this.dependentBeanMap) {
			return StringUtils.toStringArray(dependentBeans);
		}
	}

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 * @param beanName the name of the bean
	 * @return the array of names of beans which the bean depends on,
	 * or an empty array if none
	 * 返回该Bean的依赖
	 */
	public String[] getDependenciesForBean(String beanName) {
		Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
		if (dependenciesForBean == null) {
			return new String[0];
		}
		synchronized (this.dependenciesForBeanMap) {
			return StringUtils.toStringArray(dependenciesForBean);
		}
	}

 

用于判断的函数

	//这三个函数用于判断单例Bean是否正在被创建
	//返回false有两种可能
	//1、beanName不是单例bean
	//2、单例bean未处于创建状态
	public boolean isCurrentlyInCreation(String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
	}

	protected boolean isActuallyInCreation(String beanName) {
		return isSingletonCurrentlyInCreation(beanName);
	}

	/**
	 * Return whether the specified singleton bean is currently in creation
	 * (within the entire factory).
	 * @param beanName the name of the bean
	 */
	public boolean isSingletonCurrentlyInCreation(String beanName) {
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}
	/**
	 * Determine whether the specified dependent bean has been registered as
	 * dependent on the given bean or on any of its transitive dependencies.
	 * @param beanName the name of the bean to check
	 * @param dependentBeanName the name of the dependent bean
	 * @since 4.0
	 * 这两个函数用于判断dependentBeanName是否直接或是间接依赖于beanName
	 * bean与bean之间的依赖关系可以构成一张图或是一棵树,这里采用深度优先算法遍历beanName的依赖树(图),这个方法在初始化时,会检查依据depends-on属性形成的依赖图中是否有循环依赖
	 */
	protected boolean isDependent(String beanName, String dependentBeanName) {
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}

	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		String canonicalName = canonicalName(beanName);
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
			return false;
		}
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		for (String transitiveDependency : dependentBeans) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<>();
			}
			alreadySeen.add(beanName);
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

	}

 

	/**
	 * Determine whether a dependent bean has been registered for the given name.
	 * @param beanName the name of the bean to check
     * 判断是否有bean依赖于beanName对应的bean
	 */
	protected boolean hasDependentBean(String beanName) {
		return this.dependentBeanMap.containsKey(beanName);
	}

 

记录bean与bean之间的关系的函数

	/**
	 * Register a containment relationship between two beans,
	 * e.g. between an inner bean and its containing outer bean.
	 * <p>Also registers the containing bean as dependent on the contained bean
	 * in terms of destruction order.
	 * @param containedBeanName the name of the contained (inner) bean
	 * @param containingBeanName the name of the containing (outer) bean
	 * @see #registerDependentBean
	 * 记录具有包含关系的bean(内部类与外部类)
	 */
	public void registerContainedBean(String containedBeanName, String containingBeanName) {
		synchronized (this.containedBeanMap) {
			Set<String> containedBeans =
					this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
			if (!containedBeans.add(containedBeanName)) {
				return;
			}
		}
		registerDependentBean(containedBeanName, containingBeanName);
	}

	/**
	 * Register a dependent bean for the given bean,
	 * to be destroyed before the given bean is destroyed.
	 * @param beanName the name of the bean
	 * @param dependentBeanName the name of the dependent bean
	 * 记录dependentBeanName依赖于beanName,分为两步,第一步将dependentBeanName加入到依赖于
     *beanName的bean的记录项中,第二步将beanName加入到dependentBeanName的依赖记录项中
	 */
	public void registerDependentBean(String beanName, String dependentBeanName) {
		String canonicalName = canonicalName(beanName);

		synchronized (this.dependentBeanMap) {
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}

		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

 

注册实现了DisposableBean接口的类

	/**
	 * Add the given bean to the list of disposable beans in this registry.
	 * <p>Disposable beans usually correspond to registered singletons,
	 * matching the bean name but potentially being a different instance
	 * (for example, a DisposableBean adapter for a singleton that does not
	 * naturally implement Spring's DisposableBean interface).
	 * @param beanName the name of the bean
	 * @param bean the bean instance
	 */
	public void registerDisposableBean(String beanName, DisposableBean bean) {
		synchronized (this.disposableBeans) {
			this.disposableBeans.put(beanName, bean);
		}
	}

 

销毁Bean的函数

	//删除所有的单例Bean
	public void destroySingletons() {
		if (logger.isTraceEnabled()) {
			logger.trace("Destroying singletons in " + this);
		}
		//设置标志,表明现在正在销毁单例bean,不允许获得单例bean
		synchronized (this.singletonObjects) {
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		//首先调用实现了DisposableBean的bean的destroy()方法
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			destroySingleton(disposableBeanNames[i]);
		}

		//清除所有存储bean之间关系的缓存
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();

		clearSingletonCache();
	}

	/**
	 * Clear all cached singleton instances in this registry.
	 * @since 4.3.15
	 * 清楚所有的bean缓存
	 */
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

	/**
	 * Remove the bean with the given name from the singleton cache of this factory,
	 * to be able to clean up eager registration of a singleton if creation failed.
	 * @param beanName the name of the bean
	 * @see #getSingletonMutex()
	 * 移除特定的Bean的缓存
	 */
	protected void removeSingleton(String beanName) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}
	
	/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 * @param beanName the name of the bean
	 * @see #destroyBean
	 * 删除特定的单例Bean
	 */
	public void destroySingleton(String beanName) {
		// Remove a registered singleton of the given name, if any.
		removeSingleton(beanName);

		// Destroy the corresponding DisposableBean instance.
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		destroyBean(beanName, disposableBean);
	}

	/**
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * @param beanName the name of the bean
	 * @param bean the bean instance to destroy
	 * 依据深度优先删除beanName以及依赖于beanName的bean,最终会把一个依赖图谱给删除
	 */
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// Trigger destruction of dependent beans first...
		Set<String> dependencies;
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			//清除记录依赖于beanName的bean的缓存
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		if (dependencies != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			//依次删除依赖于beanName的bean
			for (String dependentBeanName : dependencies) {
				destroySingleton(dependentBeanName);
			}
		}

		// Actually destroy the bean now...
		if (bean != null) {
			try {
				//调用销毁回调
				bean.destroy();
			}
			catch (Throwable ex) {
				if (logger.isInfoEnabled()) {
					logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

		// Trigger destruction of contained beans...
		// 销毁包含关系的bean,由此可以确定,A依赖于B(A、B均实现了DisposableBean接口),则A的destroy方法比B的先调用
		Set<String> containedBeans;
		synchronized (this.containedBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
				destroySingleton(containedBeanName);
			}
		}

		// Remove destroyed bean from other beans' dependencies.
		// 这段代码没看懂,我已经看的想吐了,暂时不解释了
		synchronized (this.dependentBeanMap) {
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		//清除记录beanName的依赖关系的缓存
		this.dependenciesForBeanMap.remove(beanName);
	}

 

如何解决setter循环依赖

Bean的创建会经过三个过程:

(1)createBeanInstance:调用对象的构造方法实例化对象

(2)populateBean:填充属性,包括依赖注入

(3)initializeBean:调用init 方法

为了方便说明,这里假设有两个Bean,A与B,A与B相互通过setter函数依赖

A先通过createBeanInstance函数初始化,A是不完全的,某些依赖(B)还没有注入,会调用DefaultSingletonBeanRegistry的addSingletonFactory函数:

addSingletonFactory(beanName, new ObjectFactory<Object>() {
   @Override   public Object getObject() throws BeansException {
      return getEarlyBeanReference(beanName, mbd, bean);
   }});

A被封装成ObjectFactory,保存进singletonFactories中,A发现自己依赖于B,调用DefaultSingletonBeanRegistry的getSingleton(String beanName)函数,该函数返回值为null,A发现B还没有初始化,此时会使用createBeanInstance函数初始化B,B发现自己依赖于A,调用DefaultSingletonBeanRegistry的getSingleton(String beanName)函数,这里方便讲解,我在拷贝一遍函数:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		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();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

这个函数首先会查找singletonObjects缓存(没有查找到A),接着查找earlySingletonObjects(没有查找到A),接着会查找singletonFactories,此时会查找到之前封装了A的ObjectFactory,调用其getObject方法,获得A,接着将A放入earlySingletonObjects,此时B获得A实例,完成初始化,调用DefaultSingletonBeanRegistry的addSingleton(String beanName, Object singletonObject)方法,将自己放入singletonObjects缓存中,B初始化完成后,A也能完成初始化,调用addSingleton(String beanName, Object singletonObject)方法,从earlySingletonObjects缓存进入singletonObjects缓存,由于A可以率先初始化,所以上述过程可以完成,如果A的构造函数依赖于B,B的构造函数又依赖于A,这样两者都无法率先初始化,两者都无法率先进入singletonFactories缓存

 

如果A又与C出现setter循环依赖,C在调用DefaultSingletonBeanRegistry的getSingleton(String beanName, boolean allowEarlyReference) 方法时,会从earlySingletonObjects中获得A

 

这里总结一下三个缓存的作用:

  • singletonObjects:存储完全实例化的Bean
  • earlySingletonObjects:存储具有循环依赖的Bean
  • singletonFactories:存储未完全实例化完毕的Bean(某些依赖未注入)

这里有一个问题,为什么要多一个earlySingletonObjects,没有它,依然可以完成setter循环依赖的注入,这个我自己也还没有答案,唯一清楚的就是earlySingletonObjects中有元素意味着有setter循环依赖存在,由于spring使用双重判断加锁,加入earlySingletonObjects有助于提前返回(例如函数getSingleton(String beanName, boolean allowEarlyReference)),提高性能,继续阅读源码,可能就会有答案吧,至于构造函数循环依赖,可能通过singletonsCurrentlyInCreation来发现吧

 

总结

这个类有很大的信息量,它告诉了我很多东西

  1. spring删除bean运用了图的深度优先算法,bean之间的依赖关系本来就可以看成是图
  2. spring处理setter循环依赖的方式
  3. spring创建单例bean时运用了锁,是不是意味着bean的初始化是一个并发过程?(有待解决,现在想到的是:加锁是为了解决懒加载单例bean的初始化,spring运行后,可能使用多个线程并发处理任务(例如web服务),若多个线程同时使用一个未初始化懒加载的单例bean,此时会去初始化该bean,则需要加锁,使缓存中的单例bean只有一个)(更新:找了很久,只找到一个,结论是到5.1.0为止,spring还是单线程初始化Bean:https://jira.spring.io/browse/SPR-8767 (状态标记为未解决))
  4. 销毁回调的调用顺序
  5. spring使用双重判断加锁创建单例

本文可能会有错误,如有错误,欢迎指出

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值