在Springl下如果我们需要使用某一个bean,我们不需要手动的new一个,而是问Spring的BeanFactory拿一个你需要的Bean即可,这就是所谓的IOC,Spring控制了Bean的创建和毁灭,我们只需要问Spring拿即可。
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
BeanType bean = (BeanType)bf.getBean("beanType");
之前的文章分析了第一行代码,即将xml文件定义的Bean是如何出现在Spring容器中的,这次我就来分析在Spring容器是如何获得Bean的,也就是如何实现IOC的。
这里我就不贴上Spring源码了,这里我总结一下我通过阅读Spring源码对Spring实现IOC的认识,这里加载Bean的方式是Singleton的。我们从getBean()进入源码:
第一步:
从缓存中获得单例Bean:getSingleton()
- 从singletonObjects获得,如果不能
- 从earlySingletonObjects获得,如果不能
- Singletonfactory调用Objectfactory.getObject获得bean
- Singletonfactory删除这个factory并且bean加入earlySingletonObjects
第二步:getObjectForBeanInstance()
- 如果bean不属于FactoryBean就直接返回
- Bean属于FactoryBean就调用getObject返回需要的Bean,FactoryBean可以理解为一个代理。
如果缓存中不存在就直接加载:
第三步:重载的getSingleton()
- 检查缓存是否加载过此Bean
- 没有,就记录beanName正在加载
- 记录加载状态
- 通过ObjectFactory.getObject()实例化bean,发现bean的加载逻辑是在ObjectFactory中的createBean方法就已经定义了。
- 加载后的一些处理方法
- 删除beanName正在加载的记录
- 返回结果
直接加载Bean的核心方法:ObjectFactory中的createBean方法:
- 解析Class
- 逻辑
- 初始化之前的处理
- 调用doCreateBean()创建bean。
创建单例Bean的核心实现方法
doCreateBean()方法的逻辑:
1.创建bean的实例,调用了createBeanInstance方法
2.判断是否需要提前曝光ObjectFactory以用来解决循环依赖
3.属性注入populateBean
4.初始化Bean,initializeBean
5.注册DisposableBean,用来统一处理销毁Bean的方式。
我们逐个分析。
一、创建bean的实例:createBeanInstance:
1. 如果存在工厂方法,则使用工厂方法初始化策略
2. 否则就需要解析构造策略(使用反射或动态代理创建Bean):
1.autowireConstructor方法—表示有参数的构造:
i.确定构造参数
ii.确定构造函数
iii.转换参数类型
iv.创建bean
2.instantiateBean方法—无参的构造:默认构造函数创建bean
二、记录创建Bean的ObjectFactory:
earlySingletonExpourse,是否需要提早暴露创建ObjectFactory去解决循环依赖,创建完以后加入SingletonFactory,为以后做准备。
三、populateBean方法:
(1)判断是否进行属性填充
(2)根据注入方式byName、byType,找到依赖的Bean,然后放入PropertyValues中。
(4)调用ApplyPropertyValues,将PropertyValues注入Bean。
四、初始化Bean。initializeBean方法
在配置Bean 的时候有一个init-method属性,调用此方法完成Bean的初始化。
五、注册 DisposableBean:
如果配置了destroy-method属性,就执行reigsterDisposableBean,用来表示统一处理bean的销毁方法。