Spring 5 DefaultSingletonBeanRegistry -- getSingleton(String,ObjectFactory) 源码解析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

getSingleton(String,ObjectFactory)

返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象

  1. 如果beanName为null,抛出异常
  2. 使用单例对象的高速缓存Map作为锁,保证线程同步
  3. 从单例对象的高速缓存Map中获取beanName对应的单例对象【变量 singletonObject】,获取成功就直接返回singletonObject
  4. 如果singletonObject获取不到
    1. 如果当前在destorySingletons中【singletonsCurrentlyInDestruction】,就抛出BeanCreationNotAllowedException
    2. 如果当前日志级别时调试,就打印调试级别日志:创建单例bean的共享实例:‘beanName’
    3. 创建单例之前的回调【beforeSingletonCreation(beanName)】,默认实现将单例注册为当前正在创建中
    4. 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象【变量 newSingleton】
    5. 有抑制异常记录标记,没有时为true,否则为false 【变量 recordSuppressedExceptions】
    6. 如果没有抑制异常记录,就对抑制的异常列表【suppressedExceptions】进行实例化(LinkedHashSet)
    7. 从单例工厂中获取对象【变量 singletonObject】
    8. newSingleton设置为true,表示生成了新的单例对象
    9. 捕捉非法状态异常 【变量 ex】:
      1. 尝试从 单例对象的高速缓存Map 中获取beanName的单例对象。如果获取失败,重新抛出ex。
    10. 捕捉Bean创建异常 【变量 ex】
      1. 如果没有抑制异常记录
      2. 遍历抑制的异常列表,元素为suppressedException:将抑制的异常对象添加到 bean创建异常 中,这样其实就相当于 '因XXX异常导致了Bean创建异常‘ 的说法
      3. 抛出ex
    11. finally:
      1. 如果没有抑制异常记录,将抑制的异常列表置为null。因为suppressedExceptions是对应单个bean的异常记录, 置为null可防止异常信息的混乱
      2. 创建单例后的回调,默认实现将单例标记为不在创建中 【afterSingletonCreation(beanName)】
    12. 如果生成了新的单例对象,将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
/**
	 * Cache of singleton objects: bean name to bean instance.
	 * <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
	 * */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/**
	 * Flag that indicates whether we're currently within destroySingletons.
	 * <p>指示我们当前是否在destorySingletons中的标志</p>
	 * */
	private boolean singletonsCurrentlyInDestruction = false;
	
/**
	 * List of suppressed Exceptions, available for associating related causes.
	 * <p>抑制的异常列表,可用于关联相关原因</p>
	 * */
	@Nullable
	private Set<Exception> suppressedExceptions;
	
/**
	 * Return the (raw) singleton object registered under the given name,
	 * creating and registering a new one if none registered yet.
	 * <p>返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个
	 * 对象</p>
	 * @param beanName the name of the bean -- bean名
	 * @param singletonFactory the ObjectFactory to lazily create the singleton
	 * with, if necessary -- 必要时惰性地创建单例的ObjectFactory
	 * @return the registered singleton object -- 注册的单例对象
	 */
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    
    
		//如果beanName为null,抛出异常
		Assert.notNull(beanName, "Bean name must not be null");
		//使用单例对象的高速缓存Map作为锁,保证线程同步
		synchronized (this.singletonObjects) {
    
    
			//从单例对象的高速缓存Map中获取beanName对应的单例对象
			Object singletonObject = this.singletonObjects.get(beanName);
			//如果单例对象获取不到
			if (singletonObject == null) {
    
    
				//如果当前在destorySingletons中
				if (this.singletonsCurrentlyInDestruction) {
    
    
					//抛出不允许创建Bean异常:在工厂的单例销毁时不允许创建单例bean(请勿在destory方法中向BeanFactory请求Bean)
					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()) {
    
    
					//打印调试级别日志:创建单例bean的共享实例
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//创建单例之前的回调,默认实现将单例注册为当前正在创建中
				beforeSingletonCreation(beanName);
				//表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
				boolean newSingleton = false;
				//有抑制异常记录标记,没有时为true,否则为false
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				//如果没有抑制异常记录
				if (recordSuppressedExceptions) {
    
    
					//对抑制的异常列表进行实例化(LinkedHashSet)
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
    
    
					//从单例工厂中获取对象
					singletonObject = singletonFactory.getObject();
					//生成了新的单例对象的标记为true,表示生成了新的单例对象
					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.
					// 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态

					//因为singletonFactory.getObject()的目的就是为将beanName的
					// 单例对象注册到单例对象的高速缓存Map中,忽略掉注册后抛出的非法状态异常,可以保证
					// beanFactory不会因为该bean注册后的后续处理而导致beanFactoury的生命周期结束

					// 默认情况下,sinagletoObjects是拿不到该beanName的,但Spring的作者考虑到自定义BeanFactory的
					// 情况,但不建议在singleFactory#getObject()的方法中就注册到singletonObjects中,因为spring
					// 后面已经帮你将singleObject注册到singleObjects了。

					// 尝试从 单例对象的高速缓存Map 中获取beanName的单例对象
					singletonObject = this.singletonObjects.get(beanName);
					//如果获取失败,抛出异常。
					if (singletonObject == null) {
    
    
						throw ex;
					}
				}
				//捕捉Bean创建异常
				catch (BeanCreationException ex) {
    
    
					//如果没有抑制异常记录
					if (recordSuppressedExceptions) {
    
    
						//遍历抑制的异常列表
						for (Exception suppressedException : this.suppressedExceptions) {
    
    
							//将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
							ex.addRelatedCause(suppressedException);
						}
					}
					//抛出异常
					throw ex;
				}
				finally {
    
    
					//如果没有抑制异常记录
					if (recordSuppressedExceptions) {
    
    
						//将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
						// 可防止异常信息的混乱
						this.suppressedExceptions = null;
					}
					//创建单例后的回调,默认实现将单例标记为不在创建中
					afterSingletonCreation(beanName);
				}
				//生成了新的单例对象
				if (newSingleton) {
    
    
					//将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
					addSingleton(beanName, singletonObject);
				}
			}
			//返回该单例对象
			return singletonObject;
		}
	}

beforeSingletonCreation(beanName)

创建单例之前的回调:
如果 当前在创建检查中的排除bean名列表【inCreationCheckExclusions】中不包含该beanName 且 将beanName添加到 当前正在创建的bean名称列表【singletonsCurrentlyInCreation】后,出现beanName已经在当前正在创建的bean名称列表中添加过

/**
	 * Names of beans currently excluded from in creation checks.
	 * <p>当前在创建检查中排除的bean名</p>
	 * <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
	 * 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
	 * */
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
	
	/**
	 * Names of beans that are currently in creation.
	 * <p>当前正在创建的bean名称</p>
	 * <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
	 * 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
	 *  */
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
			
/**
	 * Callback before singleton creation.
	 * <p>创建单例之前的回调</p>
	 * <p>The default implementation register the singleton as currently in creation.
	 * <p>默认实现将单例注册为当前正在创建中</p>
	 * @param beanName the name of the singleton about to be created
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void beforeSingletonCreation(String beanName) {
    
    
		//如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName添加到 当前正在创建的bean名称列表后,出现
		// beanName已经在当前正在创建的bean名称列表中添加过
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
    
    
			//抛出 当前正在创建的Bean异常
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

afterSingletonCreation(beanName);

创建单例后的回调:
如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName从 当前正在创建的bean名称列表 异常后,出现 beanName已经没在当前正在创建的bean名称列表中出现过

	/**
	 * Names of beans currently excluded from in creation checks.
	 * <p>当前在创建检查中排除的bean名</p>
	 * <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
	 * 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
	 * */
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/**
	 * Names of beans that are currently in creation.
	 * <p>当前正在创建的bean名称</p>
	 * <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
	 * 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
	 *  */
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
			
	/**
	 * Callback after singleton creation.
	 * <p>创建单例后的回调</p>
	 * <p>The default implementation marks the singleton as not in creation anymore.
	 * <p>默认实现将单例标记为不在创建中</p>
	 * @param beanName the name of the singleton that has been created -- 已创建的单例的名称
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void afterSingletonCreation(String beanName) {
    
    
		//如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName从 当前正在创建的bean名称列表 异常后,出现
		// beanName已经没在当前正在创建的bean名称列表中出现过
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
    
    
			//抛出非法状态异常:单例'beanName'不是当前正在创建的
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

addSingleton(beanName, singletonObject)

将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:

  1. 将映射关系添加到singletonObjects【单例对象的高速缓存】中
  2. 移除beanName在singletonFactories【单例工厂缓存】中的数据
  3. 移除beanName在earlySingletonObjects【早期单例对象的高速缓存】的数据
  4. 将beanName添加到registeredSingletons【已注册的单例集】中
/**
	 * Cache of singleton objects: bean name to bean instance.
	 * <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
	 * */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/**
	 * Cache of singleton factories: bean name to ObjectFactory.
	 * <p>单例工厂的缓存:bean名称 - ObjectFactory </p>
	 * */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/**
	 * Cache of early singleton objects: bean name to bean instance.
	 * <p>早期单例对象的高速缓存:bean名称 - bean实例</p>
	 * <p>当从singletonFactories中获取到对应对象后,就会放到这个缓存中</p>
	 * */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

	/**
	 * Set of registered singletons, containing the bean names in registration order.
	 * <p>已注册的单例集,按照注册顺序包含bean名称</p>
	 * <p>用于保证工厂内的beanName是唯一的</p>
	 * */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
	
/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>将给定的单例对象添加到该工厂的单例缓存中。</p>
	 * <p>To be called for eager registration of singletons.
	 * <p>被称为渴望注册的单例</p>
	 * @param beanName the name of the bean
	 * @param singletonObject the singleton object
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
    
    
		synchronized (this.singletonObjects) {
    
    
			//将映射关系添加到单例对象的高速缓存中
			this.singletonObjects.put(beanName, singletonObject);
			//移除beanName在单例工厂缓存中的数据
			this.singletonFactories.remove(beanName);
			//移除beanName在早期单例对象的高速缓存的数据
			this.earlySingletonObjects.remove(beanName);
			//将beanName添加到已注册的单例集中
			this.registeredSingletons.add(beanName);
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108344545