1、Spring创建的bean默认是singleton模式,会以非懒加载的方式加载,即在IOC容器初始化时,容器调用getBean()方法,对bean进行实例化,同时触发依赖注入。
2、如果指定bean为prototype模式,会以懒加载的方式加载,在用户第一次调用getBean()方法时触发依赖注入。
无论是singleton模式还是prototype模式,bean的初始化与依赖注入都是通过getBean()方法触发,基本流程如下图:
1、getBean()
AbstractBeanFactory实现了BeanFactory接口,它的getBean()直接调用了doGetBean()方法,真正干活的是doGetBean()
2、doGetBean()
如果缓存中能取得我们想要的Bean,取得那些已经被创建过的Singleton的Bean,对这种Bean的请求不需要重复创建。
如果缓存中不能取得的话,并且有parentBeanFactory的话,就从parentBeanFactory中取。
如果parentBeanFactory中也取不到的话,那就根据Bean的类型(Singleton或Prototype或其它)去创建我们Bean,这里调用了下面的createBean()方法。
3、createBean()
createBean()在AbstractBeanFactory中是抽象方法,实现它的是其子类AbstractAutowireCapableBeanFactory。
在创建Bean之前,先判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入。如果配置了PostProcessor,那么这里返回创建bean的代理对象。如果没有配置PostProcessor,就调用子方法doCreateBean()去创建Bean。
4、doCreateBean()
通过createBeanInstance()方法创建bean的实例,这里生成的是一个BeanWrapper装饰器对象。
如果是单例模式,还会向容器中缓存对象,防止循环引用。
调用populateBean()方法,通过BeanDefinition,对上面生成的Bean设置Bean的属性,完成依赖注入。
调用initializeBean()方法完成bean的初始化。
5、createBeanInstance()
确认要创建Bean实例的类是否可以实例化。如果构造函数的参数使用了Autowire的话,调用autowireConstructor进行实例化。如果没有使用Autowire的话,用instantiateBean进行实例化。
6、instantiateBean()
用CGLIB对Bean进行实例化。主要是调用bean的构造函数。
7、populateBean()
先根据type或name提取要注入的bean,同一保存到PropertyValues中。然后调用applyPropertyValues()方法,将所有属性注入到前面提到BeanWrapper中。
8、applyPropertyValues()
将保存在PropertyValues取出,在完成属性解析、强制转还等一系列过程后,调用bw.setPropertyValues()方法,在该方法内最终会调用BeanWrapperImpl的内部类BeanPropertyHandler的setValue()方法,通过反射完成属性的依赖注入。
9、initializeBean()
先后执行BeanPostProcessor接口的前置处理(postProcessBeforeInitialization)、初始化逻辑、BeanPostProcessor的后置处理(postProcessAfterInitialization),其中AOP的代理对象在后置处理中创建。
getBean() --> 调用bean的构造函数 --> 依赖注入 --> bean初始化前置方法 --> bean初始化 --> bean初始化后置方法
在Bean的创建和对象依赖注入的过程中,需要通过BeanDefinition中的信息来递归地完成依赖注入。以getBean()方法为入口,通过递归,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味首和前当Bean相关的整个依赖链的注入也完成了。
在Bean创建和依赖注入完成以后,IOC容器中已经建立起一系列依靠依赖关系联系起来的Bean,通过IOC容器的相关接口和方法,可以非常方便地供上层应用使用了。