【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)

在这里插入图片描述

作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等

本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
如果此文还不错的话,还请关注、点赞、收藏三连支持一下博主~

文章目录

  • 1、debug开始
  • 2、源码开始
    • 2.1、初入源码,AnnotationConfigApplicationContext
    • 2.2、refresh()
    • 2.3、finishBeanFactoryInitialization()
    • 2.4、preInstantiateSingletons()
    • 2.5、getBean()
    • 2.6、doCreateBean
    • 2.7、getSingleton
    • 2.8、doGetBean
    • 2.9、createBean
    • 2.10、doCreateBean(beanName,mbd,args)
    • 2.11、initializeBean
  • 3、总结

1、debug开始

首先我们按照上节课的测试用例,去打2个断点,如下:
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第1张图片

然后我们启动debug模式,观察栈帧,可知其源码执行流程,

  • 注意:方法调用栈是先进后出的,也就是说,最先调用的方法会最后退出,每调用一个方法,JVM会将当前调用的方法放入栈的栈顶,方法退出时,会将方法从栈顶的位置弹出。
    【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第2张图片

2、源码开始

2.1、初入源码,AnnotationConfigApplicationContext

首先我们会启动Spring容器,进行一些列的操作,然后执行到重刷新容器refresh()这个方法,这个方法四我们Spring最重要的方法,没有之一了,他的重要性是很大的,里面的功能比如:循环依赖,国际化,环境变量,创建容器,BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor的执行等等都在这个方法中。
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第3张图片
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第4张图片

2.2、refresh()

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第5张图片
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第6张图片

2.3、finishBeanFactoryInitialization()

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第7张图片

2.4、preInstantiateSingletons()

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第8张图片

2.5、getBean()

在这里插入图片描述

2.6、doCreateBean

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第9张图片
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第10张图片

2.7、getSingleton

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第11张图片

2.8、doGetBean

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第12张图片

2.9、createBean

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第13张图片

2.10、doCreateBean(beanName,mbd,args)

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第14张图片
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第15张图片

2.11、initializeBean

【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第16张图片
在这个方法中我们可以发现执行完这个之后他是有个invokeInitMethods方法的,这个方法就是执行所有的InitializingBean的子类

3、总结

在最后的2.11中InitializeBean方法中,调用了invokeInitMethods(beanName, wrappedBean, mbd);方法,他的主要作用是执行初始化相关方法,我们可以看一下其源码
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第17张图片
可以发现他是先执行

  • 所有的InitializingBean的子类之后

然后再去调用

  • 在XML配置文件的标签中使用init-method属性指定的初始化方法;
  • 在@Bean注解中使用initMehod属性指定的方法;

这里面就是**invokeInitMethods()**方法的整体逻辑,但是大家是不是很好奇@PostConstruct和@PreDestroy在哪加载的,答案是下面这里
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第18张图片

然后再往下是下面这个for循环,@PostConstruct和@PreDestroy本质上是通过实现BeanPostProcessor去做的注解解析的,具体可以看CommonAnnotationBeanPostProcessor这个Bean的后置处理器。
【Spring【IOC】】——12、BeanPostProcessor的执行流程?(源码分析)_第19张图片
下面我们整理一下上面我们所说的代码顺序(初始化过程中)

  • @PostConstruct
  • InitializingBean
  • xml或者@Bean的init-method属性。

最后我们整理一下BeanPostProcessor的源码上下文方法

populateBean(beanName, mbd, instanceWrapper); // 给bean进行属性赋值
initializeBean(beanName, exposedObject, mbd)
{
	applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//bean的初始化前
	invokeInitMethods(beanName, wrappedBean, mbd); // 执行自定义初始化
	applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//bean的初始化后
}

你可能感兴趣的:(#,Spring,java,开发语言)