名字转化
名字转化是sping加载的第一步,为什么存在名字转化这个步骤呢,原因有一下两点:
- spring支持每个bean存在别名,并支持使用别名加载bean,所以这里需要对别名的一个转化.
- 如果spring想加载工厂bean而不是工厂生成的bean时,那么会在beanName名字前加&, 所以也需要除去& 才能获取bean.
针对以上两个需求,spring的名字转化就是解决这两个问题.具体代码如下:
1 | final String beanName = transformedBeanName(name); |
- 去除&, 这个相对比较简单,就是字符串的操作.如果判断beanName是以&开头的,直接除去该部分得到一个新的字符串.
- 别名事前已经被注册在缓存中了,只要递归地调用map的get方法,直到获取的value为null时,该key就是真实的beanName.
缓存中获取单例bean
spring为了解决bean属性循环依赖问题,会提早将创建bean的ObjectFactory曝光,曝光过程在后面会介绍.spring首先会从从缓存中获取或从缓存工厂(曝光的OjectFactory缓存)中获取bean,这样可以不等前一个bean创建完就可以直接使用暴露的工厂生成一个新的bean.
这里首先需要介绍下DefaultSingltonBeanRegistry的一些相关数据结构.
1 | //单例,保存已经创建完成的单例 |
spring首先回去缓存中查看是否该bean已经完成创建.如果不存在并且该bean正在创建中,则尝试去提早曝光的bean缓存earlySingletonObjects中获取.如果还是没有那么,看看是否允许提早曝光,如果允许并且已经提早曝光了创建这个bean的工厂ObjectFactory. 则使用这个曝光的工厂生成bean,保存到earlySingletonObjects并返回.
1 | protected Object getSingleton(String beanName, boolean allowEarlyReference) { |