Bean生命周期和九次调用BeanPostProcessor都做了什么事情

准备工作

  • 使用的是Spring5.0的源码
  • 准备一个BeanTest的测试类
    在这里插入图片描述

启动Spring

  • refresh()方法是Spring的启动方法,我们启动它
    在这里插入图片描述

refresh()

  • BeanPostProcessor会在registerBeanPostProcessors(beanFactory)注册到工厂中去
  • 我们主要看finishBeanFactoryInitialization(beanFactory)方法,这个方法是用来实例化非懒加载的Bean
    在这里插入图片描述

finishBeanFactoryInitialization(beanFactory)

  • 下边这个方法是真正开始实例化Bean
    在这里插入图片描述

preInstantiateSingletons()

  • 这个方法就是首先将所有的BeanName放入集合,然后遍历通过getBean(beanName)这个方法来获取Bean,因为我的BeanTest不是FactoryBean所以走下边的getBean(beanName)
    在这里插入图片描述
  • 进入getBean后是一个doGetBean方法然后再点进去
    在这里插入图片描述
  • 代码太多就直接找到关键方法吧,就是调用getSingleton()然后传入了beanName和一个Lambda表达式,我们进去看这个getSingleton()方法
    在这里插入图片描述
  • 加锁然后在单例池中再次get,防止被创建过,如果没有则进入创建流程通过getObject()调用Lambda表达式开始创建对象,然后上个方法进入createBean(beanName, mbd, args)
    在这里插入图片描述

createBean(beanName, mbd, args)

  • 首先找到这个方法,这是第一次调用BeanPostProcessor
    在这里插入图片描述

第一次调用BeanPostProcessor

  • 这里会调用方法applyBeanPostProcessorsBeforeInstantiation,如果这个方法返回一个对象,那么就会继续走applyBeanPostProcessorsAfterInitialization方法然后直接把这个对象加入单例池中,也就是这个对象已经走完生命周期
  • 这里Spring允许我们返回一个代理对象,然后直接不走Spring的流程
    在这里插入图片描述
  • 如果没有返回对象那么流程继续,会走到doCreateBean()方法
    在这里插入图片描述

doCreateBean()

  • 进入方法后会看到createBeanInstance方法,顾名思义这就是创建Bean实例的地方
    在这里插入图片描述

createBeanInstance()

  • 我们进入到这个方法以后能找到第二个BeanPostProcessor调用的地方
  • 这里是如果是有参构造则会走autowireConstructor方法进行解析实例化
  • 如果无参则走instantiateBean进行实例化
  • 然后返回doCreateBean方法
    在这里插入图片描述

第二次调用BeanPostProcessor

  • 进去之后发现如果实现了SmartInstantiationAwareBeanPostProcessor这个子类类型才允许对Bean做修改
  • 这一步是用来推断Bean的构造方法,实际做事情的类是AutowiredAnnotationBeanPostProcessor
    在这里插入图片描述
  • 然后在doCreateBean()中紧接着会看到第三个BeanPostProcessor被调用
    在这里插入图片描述

第三次调用BeanPostProcessor

  • 这次是要实现了MergedBeanDefinitionPostProcessor的子类才可以对Bean进行处理
  • 这步主要做的事情就是AutowiredAnnotationBeanPostProcessor解析类中有没有使用@Autowired和@Value等
  • CommonAnnotationBeanPostProcessor解析有没有@Resource注解等,还会调用父类去解析有没有@PostConstruct方法等
  • 解析完以后会封装成一个对象然后放到自己维护的一个Map缓存中,后边会进行处理
    在这里插入图片描述

第四次BeanPostProcessor

  • 这一步并没有调用,会首先判断是否支持循环依赖,如果支持会把一个Lambda表达式放入三级缓存中
  • 三级缓存是用来解决循环依赖问题的,如果循环依赖那么会调用这个表达式然后BeanPostProcessor会对Bean进行处理
    在这里插入图片描述
  • 接着我们会看到两个很重要的方法,
    在这里插入图片描述

populateBean()

  • 这个方法主要是对属性进行了注入
  • 进来以后就会看到再次调用了BeanPostProcessor

第五次调用BeanPostProcessor

  • 这一步中实现了BeanPostProcessor的子类InstantiationAwareBeanPostProcessor才能对Bean进行操作,Spring默认没有动作
  • 这里也是第一次调用BeanPostProcessor时如果返回不为null就会调用这个方法,自行扩展
  • 这个方法如果返回false则不会进行下一步的属性装配,默认返回的都是true
    在这里插入图片描述
  • 我们继续往下走就会看到第六个BeanPostProcessor

第六次调用BeanPostProcessor

  • 第六步就是上边第三步处理好@Autodwred或@Resource等注解后会调用BeanPostProcessor对需要注入的属性进行注入啊等等
  • 如果有循环依赖就会调用那个放入三级缓存中的BeanPostProcessor
    在这里插入图片描述

initializeBean()

  • 这一步是主要初始化Bean
  • 进来以后首先会调用三个Aware方法
    在这里插入图片描述
  • 然后会第七次调用BeanPostProcessor
    在这里插入图片描述

第七次调用BeanPostProcessor

  • 这里就是调用所有的BeanPostProcessor都对Bean进行操作,@PostConstruct就是在这里被调用的
  • Spring还会对实现了特定Aware接口的类进行操作
    在这里插入图片描述
  • 然后回到原来的方法,这里调用了afterPropertiesSet方法和initMethod
    在这里插入图片描述

invokeInitMethods()

  • 进来判断有没有实现InitializingBean,如果实现了就调用afterPropertiesSet方法
  • 下边还会调用initMethod方法
    在这里插入图片描述
  • 然后会再次调用BeanPostProcessor
    在这里插入图片描述

第八次调用BeanPostProcessor

  • Aop在这一步进行了代理
    在这里插入图片描述
  • 然后这些步骤走完以后就会放入一级缓存也就是单例池中,一个对象的初始化就完成了

第九次调用BeanFactoryProcessor

  • 第九次是BeanFacoty调用destroyBean删除Bean时会进行调用,这里就不带大家看了,有兴趣的可以研究一下

总结

  • 声明周期主要流程:
    • 准备创建Bean
    • 第一次调用BeanPostProcessor,判断是否为其生成代理对象,如果生成退出流程,不生成继续往下
    • 开始创建Bean
    • 第二次调用,推断出构造方法
    • 第三次调用,获取需要解析的注解如@Autowired等
    • 将半成品对象以Lambda表达式形式放入三级缓存,后边如果有循环依赖则会第四次调用
    • 准备装配属性
    • 第五次调用,允许返回false来不进行属性装配,直接开始初始化,默认为true
    • 第六次调用,通过第三次解析的数据来对Bean进行装配
    • 准备初始化
    • 先调用三个Aware方法
    • 第七次调用,@PostConstruct在这里被调用
    • 在调用afterPropertiesSet和InitMethod方法
    • 第八次调用,自己实现
    • 放入一级缓存也就是单例池中
    • 调用方法开始销毁Bean
    • 第九次调用,删除所有缓存
  • BeanPostProcessor方法调用:
    1. 允许返回一个对象直接结束初始化流程,例如返回一个代理对象
      InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
    2. 解析最合适的构造方法,如果有需要注入的参数会进行解析
      SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
    3. 解析@Autowired,@Value,@Resources,@PostConstruct等注解以便后边使用
      MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
    4. 为了解决循环依赖会放入三级缓存,可以对三级缓存中的函数式接口返回代理对象 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
    5. spring没有实现,默认返回值为true,如果返回false那么不进行属性注入 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
    6. 属性注入@Autowired,@Resources等
      InstantiationAwareBeanPostProcessor.postProcessProperties
    7. spring对实现了特定接口的类进行了操作
      BeanPostProcessor.postProcessBeforeInitialization
    8. Aop在这一步实现
      BeanPostProcessor.postProcessAfterInitialization
    9. 删除bean的操作DestructionAwareBeanPostProcessor.requiresDestruction
  • BeanPostProcessor环绕了整个Bean的生命周期,我们可以实现对应的接口来进行我们想做的任何事情,每个点我们都可以进行扩展
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值