【源码】Spring —— SingletonBeanRegistry 解读

前言

单例(singleton),是我们使用 Spring IoC Container 时最常见的 bean 实例作用域类型(Scope),因此对于单例的维护与管理,Spring 单独抽象 SingletonBeanRegistry 接口来维护

 职 责 分 明

版本

Spring 5.2.x

SingletonBeanRegistry

public interface SingletonBeanRegistry {

	/**
	 * 单例的注册,如果脱离生命周期单独调用该方法,就是单纯的注册而不执行
	 * 		诸如生命周期回调等相关
	 * 通常,是容器在基于 BeanDefinition 创建 singleton 时调用该方法的
	 */
	void registerSingleton(String beanName, Object singletonObject);

	/**
	 * 获取以及实例化完成的 singleton
	 * 1)手动 registerSingleton 注册的
	 * 2)容器基于 BeanDefinition 实例化完成后注册的
	 */
	@Nullable
	Object getSingleton(String beanName);

	/**
	 * 检查指定 singleton 是否存在
	 * 该方法 + ListableBeanFactory#containsBeanDefinition:可以查看当前容器中是否可以
	 * 		获取到指定 name 的 bean,无论它是否实例化完成
	 * BeanFactory#containsBean 在上一步基础上,还可以查找父级容器		
	 */
	boolean containsSingleton(String beanName);

	// 上述 singleton 名称数组
	String[] getSingletonNames();

	// 上述 singleton 个数
	int getSingletonCount();

	// 单例锁对象
	Object getSingletonMutex();

}
  • XXXRegistry,这种命名在 Spring 中通常扮演注册中心的职责,维护管理对应的一组实例,此处管理的就是 singleton,即容器中最常见作用域的实例
  • 单例通常来自 Spring IoC Container 在配置解析后,基于 BeanDefinition 的注册
  • 同时我们也可以在容器生命周期之外自行调用 registerSingleton 方法注册,对于这部分实例的生命周期,自然不由容器管理
  • 该接口提供的方法就是基于上述两种 singleton 而言

DefaultSingletonBeanRegistry

核心属性

	// 单例缓存 beanName -> 单例实例
	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);

	// 缓存以及注册单例的单例名称(按注册顺序)
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	// 正在创建的 bean 的 name
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	// 是否允许 循环引用
	private boolean singletonsCurrentlyInDestruction = false;

	//...
  • 定义了大量的 缓存 属性,用于解决 循环依赖提高性能
  • 其中 singletonObjects 即我们常说的 单例池,所有的 单例 都在创建完成后缓存其中

registerSingleton(String beanName, Object singletonObject)

	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {

		// 重复注册抛异常 IllegalStateException
		synchronized (this.singletonObjects) {
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("...");
			}

			// 单例注册
			addSingleton(beanName, singletonObject);
		}
	}

	protected void addSingleton(String beanName, Object singletonObject) {
		/**
		 * 加入一级缓存
		 * 二三级缓存移除
		 * registeredSingletons 缓存 beanName
		 */
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

单例注册, 即放入 singletonObjects 单例池中,并清除其他无效缓存

getSingleton(String beanName)

	// 单例获取
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

	@Nullable
	// 获取目标单例,没有则创建
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	
		// 一级缓存获取
		Object singletonObject = this.singletonObjects.get(beanName);

		// 未获取到且未在创建中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

			// 三级缓存获取
			singletonObject = this.earlySingletonObjects.get(beanName);

			// 获取不到且允许循环依赖,继续去二级缓存获取
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					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;
	}
  • 试图获取单例,会依次从各级 缓存 中获取
  • 二级缓存 内部是提前暴露的 单例工厂三级缓存 是将 单例工厂 创建的实例缓存起来,它们是分别为了解决 循环依赖优化性能

getSingleton(String beanName, ObjectFactory<?> singletonFactory)

	// 从给定 singletonFactory 创建对应单例并注册
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {

		synchronized (this.singletonObjects) {

			// 一级缓存获取
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {

				// 正在创建中抛异常
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"...");
				}

				// 加入 singletonsCurrentlyInCreation 缓存
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);

				// 初始化 suppressedExceptions
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 单例工厂获取对应单例实例
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					//...
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}

					// 从 singletonsCurrentlyInCreation 移除
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {

					// 注册单例
					addSingleton(beanName, singletonObject);
				}
			}

			// 返回
			return singletonObject;
		}
	}

从给定 单例工厂 创建对应 单例 并注册

其他方法

	// 单例移除,从所有缓存中移除
	protected void removeSingleton(String beanName) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}

	@Override
	// 是否存在指定 beanName 对应的 单例
	public boolean containsSingleton(String beanName) {
		return this.singletonObjects.containsKey(beanName);
	}

	@Override
	// 获取所有单例 name
	public String[] getSingletonNames() {
		synchronized (this.singletonObjects) {
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}

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

FactoryBeanRegistrySupport

有一部分单例可能会是 FactoryBean,这部分单例的相关方法由 FactoryBeanRegistrySupport 拓展 DefaultSingletonBeanRegistry 提供

属性

	// bean 缓存 (FactoryBeanName -> bean实例)
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

FactoryBean 维护的单例的缓存

getTypeForFactoryBean(FactoryBean<?> factoryBean)

	@Nullable
	// 确定给定 工厂bean 的类型
	protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
		try {
			// ...
			else {
				return factoryBean.getObjectType();
			}
		}
		catch (Throwable ex) {
			// 略
		}
	}

FactoryBean 的类型获取,实际就是 factoryBean.getObjectType()

getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)

	// 获取 工厂bean 对应的 bean实例
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		
		// 是单例bean && 已注册
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				
				// 获取工厂缓存的 bean
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {

					// 从 工厂bean 获取 bean实例
					object = doGetObjectFromFactoryBean(factory, beanName);
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						// 有必要的话调用 后处理 方法
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								// 后处理
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								//...
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		// 不是单例 || 还没注册过
		else {
			// 获取单例实例
			Object object = doGetObjectFromFactoryBean(factory, beanName);

			// 有必要的话调用 后处理 方法
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					//...
				}
			}
			return object;
		}
	}
  • 最终都是委托到方法 doGetObjectFromFactoryBean
  • 这里允许对获取的实例进行后处理,比如执行 post processor

doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName)

	// 获取指定 工厂bean 创建的 bean实例
	private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
		Object object;
		try {
			if (System.getSecurityManager() != null) {
				// 略
			}
			else {
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			// 略
		}

		// 略
		
		return object;
	}

简单地说就是 FactoryBean#getObject

postProcessObjectFromFactoryBean(Object object, String beanName)

	// 后处理方法由子类复写
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
		return object;
	}

对最终的实例进行后处理

如果目标 `bean` 实例是个 `FactroyBean`,那容器的生命周期只
对该 FactroyBean 生效,因此此处允许对真正的实例进行后处理

比如 AbstractAutowireCapableBeanFactory 会覆写该方法:执
行容器中所有的 BeanPostProcessor#postProcessAfterInitialization

其他方法

	// 获取给定 beanName 和 bean实例 对应的 工厂bean
	protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanCreationException(beanName,
					"...");
		}
		return (FactoryBean<?>) beanInstance;
	}

	@Override
	// 单例移除,同时从本类的缓存中移除
	protected void removeSingleton(String beanName) {
		synchronized (getSingletonMutex()) {
			super.removeSingleton(beanName);
			this.factoryBeanObjectCache.remove(beanName);
		}
	}

	@Override
	// 清缓存同理
	protected void clearSingletonCache() {
		synchronized (getSingletonMutex()) {
			super.clearSingletonCache();
			this.factoryBeanObjectCache.clear();
		}
	}

	// ...

还提供了 FactoryBean 的获取、单例移除 等方法

总结

SingletonBeanRegistry 接口把容器对 singleton 的维护管理单独抽象了出来,其中:

  • DefaultSingletonBeanRegistry 提供对常规单例的维护,其最终会维护在一个缓存 Map 中即我们通常所说的 单例池,同时它借助 二级缓存(工厂缓存) 三级缓存(优化二级缓存创建实例的开销) 来解决 循环依赖 的问题
  • 针对 FactoryBean 类型的 singleton,对应的方法由 FactoryBeanRegistrySupport 提供,比如 类型的获取 最终实例的获取 实例后处理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值