- 前言
- 第一部分 核心实现
- 第 1 章 Spring 整体架构和环境搭建
- 第 2 章 容器的基本实现
- 第 3 章 默认标签的解析
- 第 4 章 自定义标签的解析
- 第 5 章 bean 的加载
- 第 6 章 容器的功能扩展
- 第 7 章 AOP
- 第二部分 企业应用
- 第 8 章 数据库连接 JDBC
- 第 9 章 整合 MyBatis
- 第 10 章 事务
- 第 11 章 SpringMVC
- 第 12 章 远程服务
- 第 13 章 Spring 消息
5.2 缓存中获取单例 bean
介绍过 FactoryBean 的用法后,我们就可以了解 bean 加载的过程了。前面已经提到过,单例在 Spring 的同一个容器内只会被创建一次,后续再获取 bean 直接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从缓存中加载,然后再次尝试尝试从 singletonFactories 中加载。因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖, Spring 创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建时需要依赖上个 bean,则直接使用 ObjectFactory。
public Object getSingleton(String beanName) {
//参数 true 设置标识允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
//如果此 bean 正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候则会调用 addSingletonFactory 方法将对应
的 ObjectFactory 初始化策略存储在 singletonFactories
(beanName);
ObjectFactory singletonFactory = this.singletonFactories.get
if (singletonFactory != null) {
//调用预先设定的 getObject 方法
singletonObject = singletonFactory.getObject();
//记录在缓存中,earlySingletonObjects 和 singletonFactories 互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
这个方法因为涉及循环依赖的检测,以及涉及很多变量的记录存取,所以让很多读者摸不着头脑。这个方法首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingleton Objects 里面获取,如果还获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory,然后调用这个 ObjectFactory 的 getObject 来创建 bean,并放到 earlySingleton Objects 里面去,并且从 singletonFacotories 里面 remove 掉这个 ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在 allowEarlyReference 为 true 的情况下才会使用。
这里涉及用于存储 bean 的不同的 map,可能让读者感到崩溃,简单解释如下。
singletonObjects:用于保存 BeanName 和创建 bean 实例之间的关系,bean name --> bean instance。
singletonFactories:用于保存 BeanName 和创建 bean 的工厂之间的关系,bean name -->ObjectFactory。
earlySingletonObjects:也是保存 BeanName 和创建 bean 实例之间的关系,与 singletonObjects 的不同之处在于,当一个单例 bean 被放到这里面后,那么当 bean 还在创建过程中,就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。
registeredSingletons:用来保存当前所有已注册的 bean。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论