插手“容器的启动”——BeanPostProcessor 篇

197 阅读1分钟

插手“容器的启动”——BeanPostProcessor 篇

Spring的IoC容器在实现的时候,存在容器启动阶段和Bean实例化阶段。

Spring充分运用了这两个实现阶段的不同特点,在每个阶段都加入了相应的容器扩展点,以便我们可以根据具体场景的需要加入自定义的扩展逻辑。

本文着重于Spring启动过程中的Bean实例化阶段(createBean阶段)

Spring提供了一种叫做BeanPostProcessor的容器扩展机制,那么我们该如何去扩展呢?

下边是涉及到的processors

  1. InstantiationAwareBeanPostProcessor extends BeanPostProcessor
  2. MergedBeanDefinitionPostProcessor extends BeanPostProcessor
  3. BeanPostProcessor

createBean源码分析

源码太长,我总结成了以下的步骤图

![未命名文件 (qb1771xly.bkt.clouddn.com/未命名文件 (1).jpg)](C:\Users\Administrator\Downloads\未命名文件 (1).jpg)

从图可以看出,执行顺序大致如下

  1. 执行 bean = InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiationbean如果为null,走3,不为null,走2
  2. 代理对象生成后 执行BeanPostProcessor.postProcessAfterInitialization 注意这里不是InstantiationAwareBeanPostProcessor,执行完直接返回Bean,方法结束
  3. 没有代理对象,则直接创建对象。此时属性未赋值,此处使用策略模式,正常情况下走SimpleInstantiationStrategy.instantiate,如果存在方法注入,走spring的cglib的代理
  4. 执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
  5. 此时对象创建完成,执行InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
  6. pvs =InstantiationAwareBeanPostProcessor.postProcessProperties如果pvs为空,pvs=InstantiationAwareBeanPostProcessor.postProcessPropertyValues
  7. 在init之前执行BeanPostProcessor.postProcessBeforeInitialization
  8. init,执行初始化方法,包括init-method和继成InitializingBean
  9. init之后执行``BeanPostProcessor.postProcessAfterInitialization`
  10. 返回Bean

这里根据单词可以稍微对记忆有些帮主

  • Instantiation 实例化
  • Initialization 初始化

我们知道bean是先实例化再初始化的,所以大致顺序是

  1. postProcessBeforeInstantiation
  2. postProcessAfterInstantiation
  3. postProcessBeforeInitialization
  4. postProcessAfterInitialization