Spring源码之bean的加载(二)获取单例bean

来源:互联网 发布:利比亚知乎 编辑:程序博客网 时间:2024/04/20 04:26

我们知道,单例bean在系统的加载只加载一次,后期如果想用到对应的bean的话,那么就应该去缓存中获取。当然,首先是尝试去缓存中加载,然后再尝试从singletonFactories中加载。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)


 通过上面的时序图,我们可以找到对应的源码,首先我们看到的是AbstractBeanFactory中的getBean()的函数,之后,又会去调用doGetBean(),其次就到到DefaultSingletonBeanRegistry.

@Overridepublic Object getSingleton(String beanName) {return getSingleton(beanName, true);}

/** * Return the (raw) singleton object registered under the given name. * <p>Checks already instantiated singletons and also allows for an early * reference to a currently created singleton (resolving a circular reference). * @param beanName the name of the bean to look for * @param allowEarlyReference whether early references should be created or not * @return the registered singleton object, or {@code null} if none found */protected Object getSingleton(String beanName, boolean allowEarlyReference) {//检查缓存中是否存在实例Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//如果为空,则锁定全局变量进行处理synchronized (this.singletonObjects) {//如果此bean正在加载则不处理singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {//当某个些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略//存储在singletonFavtoriesObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//调用预先设定的getObject方法singletonObject = singletonFactory.getObject();//记录在缓存中,earlySingletonObjects和singletonFactoriesthis.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return (singletonObject != NULL_OBJECT ? singletonObject : null);}

这个方法因为涉及循环依赖的检测,以及涉及很多变量的记录存取,所以让很多读者摸不着头脑。这个方法首先尝试从singletonObjects里面获取实例,如果获取不到再从earlySingleton Object里面获取,如果还获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getobject来创建bean,并收到earlySingleton Objects里面去,并且从singletonFactory里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyRactory为true的情况下才会使用。


0 0
原创粉丝点击