Spring源码解析——4、bean的加载
bean的加载
对于加载bean的功能,spring中的调用方式为:
ApplicationContext bf = new ClassPathXmlApplicationContext("spring/spring.xml");
User user = (User) bf.getBean("testBean");
Spring加载bean的步骤:
转换对应beanName
尝试从缓存中加载单例
bean的实例化
原型模式的依赖检查
检查ParentBeanFactory
将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
寻找依赖
针对不同的scope进行bean的创建
类型转换
1、FactoryBean的使用
一般情况下,spring通过反射机制利用bean的class属性指定实现类来实例化bean。
2、缓存中获取单例bean
从getSingleton方法中获取bean。
单例在spring的同一个容器只会被创建一次,后续在获取bean直接从单例缓存中获取。
-
singletonObjects:用于保存beanName和创建bean实例之间的关系;
-
singletonFactories:用于保存beanName和创建bean的工厂之间的关系;
-
earlySingletonObjects:也是保存beanName和创建bean实例之间的关系,与singletonFactories不同的是,当一个bean实例被放到这个里边之后,那么当bean还在创建过程中,就可以通过getBean方法获取到了,其目的是用来检测循环依赖;
-
registeredSingletons:用来保存当前所有已注册的bean
3、从bean的实例中获取对象
从getObjectForBeanInstance方法中获取bean实例的步骤:
- 对FactoryBean正确性的验证
- 对非FactoryBean不做任何处理
- 对bean进行转换
- 将从Factory中解析bean的工作委托给getObjectFromFactoryBean方法
4、获取单例bean
从getSingleton方法中获取bean的步骤:
- 检查缓存是否已经加载过
- 若没有加载,则记录beanName的正在加载状态
- 加载单例前记录加载状态
- 通过调用参数传入的ObjectFactory的个体Object方法实例化bean
- 加载单例后的处理方法调用
- 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
- 返回处理结果
5、准备创建bean
- 通过ObjectFactory接口的方法getObject
- 找到AbstrctBeanFactory中的doGetBean方法中的getSingleton方法
- 找到createBean方法
createBean方法的步骤:
- 根据设置的class属性或者根据className属性来解析class
- 对oveirrde属性进行验证及标记
- 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
- 创建bean
5.1 处理oveirrde属性
在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrids属性里。
5.2 实例化的前置处理
Spring中的规则是在bean的初始化后尽可能将注册的后处理器的applyBeanPostProcessorsAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,则不会再经理bean的初始化创建过程。
6、循环依赖
6.1 什么是循环依赖
即循环引用
6.2 Spring如何解决循环依赖
在Spring中将循环依赖的处理分成了三种情况:
1、构造器循环依赖
表示通过构造器注入构成的循环依赖,此依赖事无法解决的
2、setter循环依赖
表示通过setter注入方式构成的循环依赖,只能解决单例作用域的bean循环依赖
3、prototype范围的依赖处理
对于‘prototype’作用域bean,Spring容器无法完成依赖注入,因为spring容器不进行缓存‘prototype’作用域的bean,因此无法提前暴露一个创建中的bean
7、创建bean
常规bean的创建就是在doCreateBean方法中完成的,步骤如下:
1、如果是单例则需要先进行清除缓存
2、实例化bean,将BeanDefinition转换为BeanWrapper
3、MergedBeanDefinitionPostProcessor的应用,Autowire注解正是通过此方法实现诸
4、如类型的预解析
5、依赖处理
6、属性填充
7、循环依赖检查
8、注册DisposableBean,如果配置了destroy-method,这里需要注册以便于在销毁时来调用
9、完成创建并返回
7.1创建bean的实例
reateBeanInstance方法