缓存中获取单例bean getSingleton

DefaultSingletonBeanRegistry 中实现此方法

1
2
3
4
5
6
7
8
//这个map维护了单例对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//当前正在创建中的单例对象
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
//早期单例对象
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
//单例工厂?
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
//如果根据这个beanName没取到对象,但发现这个对象还在创建中.....
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
//如果早期单例对象中没有此bean,并且允许早期依赖
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候则会调用 addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中,earlySingletonObjects 和 singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}

这里还是看得迷迷糊糊的,毕竟一来就各种取值, 往后看看在哪塞值的吧!

从bean的实例中获取对象 getObjectForBeanInstance

​ 我们得到bean的实例后要做的第一步都是调用这个方法来检测一下正确性,其实就是用于检测当前bean是否是FactoryBean 类型的bean,如果是,就要调用getObject() 方法作为返回值

FactoryBean 在之前我们便已经接触过.

getObjectForBeanInstance 方法就不贴了, 主要就是各种验证, 取缓存等等, 里面需要注释的一段如下

1
2
3
4
5
   	//将存储XML配置文件的GernericBeanDefinition 转换为RootBeanDefinition,
//如果指定BeanName是子bean的话,同时会合并父类的相关属性
if (mbd == null && this.containsBeanDefinition(beanName)) {
mbd = this.getMergedLocalBeanDefinition(beanName);
}

​ 方法中的关键是 getObjectFromFactoryBean , 实现类为 FactoryBeanRegistrySupport

​ 而 getObjectFromFactoryBean 方法中也还不是最核心的, 其代码主要是保证单例bean的全局唯一. 如果是单例,那就不用重复创建,可以使用缓存来提高性能. 另外方法还根据需要对bean进行了后处理postProcessObjectFromFactoryBean()

后处理即是遍历所有的bean后处理器,在bean初始化后调用它的处理方法,后面还会详细学习.

​ 它的关键是 doGetObjectFromFactoryBean ,方法名前面多加了个do…

在这个方法里面,我们终于看到想要看到的 `object = factory.getObject();`  ,虽然早已知道必须要走到这,但是到这一步`getObject()` 还是绕了很多路,包括到这里居然还使用了`java.security.AccessController` 权限验证...