![]()
前面随笔中,结束了对配置文件的解析工作,以及将配置文件转换成对应的BeanDefinition存储在容器中。接下来就该进行bean的加载了。
在这段代码中,我们可以看出bean的加载经历了一个相当复杂的过程,并不是我们想象中简单的用bean的class属性通过反射的方式来实例化bean。其中涉及到方方面面的考虑,不得不佩服开发者缜密的思维。
对于bean加载的过程大致可以总结如下:
1、转换对应的beanName
这里的目的是通过name得到真正的beanName。singleton bean
在BeanFactoryUtils.transformedBeanName()中将name前的‘&’符号去除。之前的随笔中有说到过,Spring除了可以通过我们常见的set注入和构造器注入的方式生成bean,还可以通过工厂方法来实例化bean。例如
这样通过beanFactory.getBean() 得到的bean就是通过MyBeanFactory实现FactoryBean的getObject()方法实例化而来的。
如果我们想要得到的MyFactoryBean本身这个bean的话,就需要在beanName前加上‘&’符号。例beanFactory.getBean("&production")
回到之前的代码中,处理完‘&’符号的name之后,在cannonicalName()方法里会遍历容器中aliasMap中维护的alia对应beanName的关系,得到真正的beanName
2、尝试从缓存中加载单例
因为单例的bean只需要初始化一次就足够了,因此在spring中,实例化过得单例bean都被存放在了缓存中,一旦后续再尝试获取该bean时,只需要从缓存中获取就足够了。
在读spring的源码时,经常被spring容器中的各种缓存搞的云里雾里,所以在解读之前先把我们将要用到的缓存名以及其用意列举一下。
singletonObjects:
维护了容器中已被实例化过的单例bean。通过beanName -> Object

factoryBeanObjectCache:
维护了容器中单例工厂FactoryBean对象getObject()得到的单例bean。通过beanName -> Object
singletonsCurrentlyInCreation:
存放了当前正在实例化中的单例bean beanName的集合。 Set<beanName>
earlySingletonObjects:
维护了容器中单例bean。通过beanName -> Object。和singletonObjects的区别是singletonObjects中存放的是已经实例化完成的bean,而在一个bean还未实例化完成时,spring就会通过对应的ObjectFactory的getObject()方法返回一个bean的引用并存放在earlySingletonObjects中,对于后面可能遇到的循环依赖有大用处。
singletonFactories:
维护了容器中还未生产过单例的ObjectFactory。通过beanName -> ObjectFactory。一旦某个ObjectFactory生产过bean,则这个bean会被放置到earlySingletonObjects中,并且这个ObjectFactory在singletonFactories中会被移除。
接下来结合getObjectForBeanInstance方法的代码一起看
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-58005-1.html
好帅啊
可口可乐
亲爱的