Spring关于Bean的加载

本专栏参考文献《Spring源码深度解析》

在对xml配置文件解析完成之后,开始进行bean加载。此过程十分复杂,大致流程如下:

  1. 转换对应beanName  
  2. 尝试从缓存中加载单例
  3. bean的实例化
  4. 原型模式的依赖检查
  5. 检测parentBeanFactory
  6. 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition
  7. 寻找依赖
  8. 针对不同的scope进行bean创建
  9. 类型装换

简述:

1.转换对应beanName:

AbstractoryBeanFactory.transformedBeanName(String name)

这里的入参可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,解析内容包含如下几点:

  • 去除FactoryBean的修饰符,例如:如果name="&aa",那么会首先去除&符号,使得name="aa"
  • 取指定alias所表示的最终beanName,例如:别名A指向名称为B的bean则返回B;若别名A指向别名B,别名B指向名称为C的bean,则返回C

2.尝试从缓存中加载单例

单例在Spring的同一个容器内只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。当然这里只是尝试加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例Bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建的bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory

3.Bean的实例化

如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean。例如:我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。

4.原型模式的依赖检查

只有在单例情况下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完成的时候由于对于B的创建再次返回创建A,造成循环依赖,也就是isPrototypeCurrentlyInCreation(beanName)判断true

5.检测parentBeanFactory

如果缓存没有数据的话直接转到父类工厂上去加载了。如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试夹杂了,然后再递归调用getBean方法

6.将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition

因为从XML配置未见中读取到的bean信息是存储在GenericBeanDefinition中的,但是所有的bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。

7.寻找依赖

因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以在spring的加载顺序中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖

8.针对不同的scope进行bean的创建

在spring中存在不同的Scope,默认使用singleton即单例,但是还有些其他的配置诸如prototype、request之类的,在这个步骤中spring会根据不同的配置进行不同的初始化策略。

9.类型转换

程序到这一步,返回bean后已经基本结束了,通常对该方法的调用参数requiredType是空的,但是可能会存在这一的情况,返回的bean其实是个String,但是requiredType却传入Integer类型,那么这时候本步骤就会起作用,它的功能是将返回的bean转换为requiredType所指定的类型。当然,String转换为Integer是最简单的一种转换,在Spring中提供了各种各样的转换器,用户也可以自己扩展转换器来满足需求。

几个关键类及数据结构:

Map<String,BeanDefinition> beanDefinitionMap:存放所有已经加载的类

AbstractBeanFactory: 该类的doGetBean()方法为bean加载的入口

ObjectFactory:

FactoryBean:

GernericBeanDefinition:存储XML配置文件

RootBeanDefinition:

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值