在spring学习之源码分析--AbstractApplicationContext之refresh中,提及了容器初始化时调用createBean创建bean,但是没有细讲,这边就详细的讲解一下。
createBean
- 解析class类型
- 如果有lookup-method和replaced-method属性先处理。如果有某个属性,就调用动态代理,进行相应的拦截。另外,有些方法可能存在重载的情况,在这里也会一并处理了,如果只有一个方法名,会标记为没有重载,这样后面调用方法的时候,就可以直接调用了。
- resolveBeforeInstantiation,先判断是否解析过了,如果没有,看看InstantiationAwareBeanPostProcessor能不能生成bean--applyBeanPostProcessorsBeforeInitialization,这个bean不一定是普通的bean,也可能是动态代理或者其他方式生成的bean。如果可以生成bean,就标志位解析过了,并且调用后置处理器处理--applyBeanPostProcessorsAfterInitialization。
- 如果没有生成,调用doCreateBean方法,下面我们看看这部分内容
doCreateBean
- 如果是单例,取出bean并清空缓存。
- 如果取出的bean为空,实例化bean,具体实例化过程下面讲解。
- 创建后,MergedBeanDefinitionPostProcessor进行后置处理,这个MergedBeanDefinitionPostProcessor包括AutowiredAnnotationBeanPostProcessor等。
- 依赖处理
- 实例化后,对bean各个属性进行赋值。见populateBean。
- 赋值后,调用init方法,InitializingBean这些。见initializeBean
- 再检查一下依赖,看看是不是初始化方法改变了什么
- 根据scope注册DisposableBean,registerDisposableBeanIfNecessary方法
createBeanInstance
- 先检查是否有类的访问权限,如果没有权限,只能抛异常了
- 看看有没有Supplier回调,如果有回调,就让别人回调创建
- 看看有没有工厂方法回调,如果有回调,就让工厂方法回调创建
- 如果没有其他人插手了,就开始自己创建了。实例化类要么有参构造要么无参构造,由于每次解析很耗性能,所以要把构造结果缓存起来。既然有缓存,当然是先查询是否有缓存,如果有,再根据缓存选择无参构造还是有参构造。
- 如果缓存没有,就去解析,解析后缓存结果,以及选择无参构造还是有参构造。
populateBean
populateBean方法
实例化了bean,给bean的属性赋值。
- 先判断是否有属性需要赋值
- InstantiationAwareBeanPostProcessor后置处理,是否继续填充属性。我们可以看到,spring在很多阶段做了很多这类后置处理。
- 根据名称或类型,获取需要注入的bean。根据name比较简单,就是getBean,根据类型解析就有点复杂了。
- 赋值前,InstantiationAwareBeanPostProcessor后置处理验证属性
- 依赖检查
- 赋值
initializeBean
initializeBean方法
bean构造完了,也给各个属性赋值了,先在就看看有没有初始化方法了。
- Aware处理,也就是说,如果实现了Aware接口,会注入一些属性给这些bean
- 后置处理器处理,调用BeanPostProcessor的postProcessBeforeInitialization
- invokeInitMethods,如果实现了InitializingBean 接口,就调用他的afterPropertiesSet方法,如果有自定义方法,就继续调用自定义方法。例子请查看spring学习之bean生命周期的管理
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。