spring学习之源码分析--AbstractApplicationContext之refresh中,提及了容器初始化时调用createBean创建bean,但是没有细讲,这边就详细的讲解一下。

createBean

  1. 解析class类型
  2. 如果有lookup-method和replaced-method属性先处理。如果有某个属性,就调用动态代理,进行相应的拦截。另外,有些方法可能存在重载的情况,在这里也会一并处理了,如果只有一个方法名,会标记为没有重载,这样后面调用方法的时候,就可以直接调用了。
  3. resolveBeforeInstantiation,先判断是否解析过了,如果没有,看看InstantiationAwareBeanPostProcessor能不能生成bean--applyBeanPostProcessorsBeforeInitialization,这个bean不一定是普通的bean,也可能是动态代理或者其他方式生成的bean。如果可以生成bean,就标志位解析过了,并且调用后置处理器处理--applyBeanPostProcessorsAfterInitialization
  4. 如果没有生成,调用doCreateBean方法,下面我们看看这部分内容

doCreateBean

doCreateBean方法

  1. 如果是单例,取出bean并清空缓存。
  2. 如果取出的bean为空,实例化bean,具体实例化过程下面讲解。
  3. 创建后,MergedBeanDefinitionPostProcessor进行后置处理,这个MergedBeanDefinitionPostProcessor包括AutowiredAnnotationBeanPostProcessor等。
  4. 依赖处理
  5. 实例化后,对bean各个属性进行赋值。见populateBean。
  6. 赋值后,调用init方法,InitializingBean这些。见initializeBean
  7. 再检查一下依赖,看看是不是初始化方法改变了什么
  8. 根据scope注册DisposableBean,registerDisposableBeanIfNecessary方法

createBeanInstance

createBeanInstance方法

  1. 先检查是否有类的访问权限,如果没有权限,只能抛异常了
  2. 看看有没有Supplier回调,如果有回调,就让别人回调创建
  3. 看看有没有工厂方法回调,如果有回调,就让工厂方法回调创建
  4. 如果没有其他人插手了,就开始自己创建了。实例化类要么有参构造要么无参构造,由于每次解析很耗性能,所以要把构造结果缓存起来。既然有缓存,当然是先查询是否有缓存,如果有,再根据缓存选择无参构造还是有参构造。
  5. 如果缓存没有,就去解析,解析后缓存结果,以及选择无参构造还是有参构造。

populateBean

populateBean方法
实例化了bean,给bean的属性赋值。

  1. 先判断是否有属性需要赋值
  2. InstantiationAwareBeanPostProcessor后置处理,是否继续填充属性。我们可以看到,spring在很多阶段做了很多这类后置处理。
  3. 根据名称类型,获取需要注入的bean。根据name比较简单,就是getBean,根据类型解析就有点复杂了。
  4. 赋值前,InstantiationAwareBeanPostProcessor后置处理验证属性
  5. 依赖检查
  6. 赋值

initializeBean

initializeBean方法
bean构造完了,也给各个属性赋值了,先在就看看有没有初始化方法了。

  1. Aware处理,也就是说,如果实现了Aware接口,会注入一些属性给这些bean
  2. 后置处理器处理,调用BeanPostProcessor的postProcessBeforeInitialization
  3. invokeInitMethods,如果实现了InitializingBean 接口,就调用他的afterPropertiesSet方法,如果有自定义方法,就继续调用自定义方法。例子请查看spring学习之bean生命周期的管理

大军
847 声望183 粉丝

学而不思则罔,思而不学则殆