spring 3.2 源码如下:
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 != NULL_OBJECT ? singletonObject : null);
}
说明:
首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingletonObjects中获取,如果还是获取不到,再尝试从singletonFactories里面获取beanName对应的objectFactory,然后调用getObject来创建bean。并放到earlySingletonObjects里面去,并从singletonFactories里去掉。
这里涉及到不少Map
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
1.singletonObjects : 用于保存beanName和创建bean实例之间的关系
2.singletonFactories : 用于保存beanName和创建bean的工厂之间的关系
3.earlySingletonObjects :也是保存beanName和bean实例之间的关系,与singletonObjects 的不同之处在于,当一个单例bean被放在这里后,那么当bean还在创建过程中,就可以通过getBean的方法获取了,其目的是用来检测循环引用。
4.registeredSingletons : 用于保存当前所有已注册的bean。