📫作者简介: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个断点,如下:
然后我们启动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的初始化后
}