【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个断点,如下:
在这里插入图片描述

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

  • 注意:方法调用栈是先进后出的,也就是说,最先调用的方法会最后退出,每调用一个方法,JVM会将当前调用的方法放入栈的栈顶,方法退出时,会将方法从栈顶的位置弹出。
    在这里插入图片描述

2、源码开始

2.1、初入源码,AnnotationConfigApplicationContext

首先我们会启动Spring容器,进行一些列的操作,然后执行到重刷新容器refresh()这个方法,这个方法四我们Spring最重要的方法,没有之一了,他的重要性是很大的,里面的功能比如:循环依赖,国际化,环境变量,创建容器,BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor的执行等等都在这个方法中。
在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这个方法中我们可以发现执行完这个之后他是有个invokeInitMethods方法的,这个方法就是执行所有的InitializingBean的子类

3、总结

在最后的2.11中InitializeBean方法中,调用了invokeInitMethods(beanName, wrappedBean, mbd);方法,他的主要作用是执行初始化相关方法,我们可以看一下其源码
在这里插入图片描述
可以发现他是先执行

  • 所有的InitializingBean的子类之后

然后再去调用

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

这里面就是**invokeInitMethods()**方法的整体逻辑,但是大家是不是很好奇@PostConstruct和@PreDestroy在哪加载的,答案是下面这里
在这里插入图片描述

然后再往下是下面这个for循环,@PostConstruct和@PreDestroy本质上是通过实现BeanPostProcessor去做的注解解析的,具体可以看CommonAnnotationBeanPostProcessor这个Bean的后置处理器。
在这里插入图片描述
下面我们整理一下上面我们所说的代码顺序(初始化过程中)

  • @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的初始化后
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhz小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值