前面给大家介绍了springboot启动的核心流程,本文开始给大家详细的来介绍springboot启动中的具体实现的相关细节。
springboot2.png
首先我们来看下在springapplication的构造方法中是如何帮我们完成这4个核心操作的。
image.png
1 @suppresswarnings({ "unchecked", "rawtypes" }) 2 public springapplication(resourceloader resourceloader, class<?>... primarysources) { 3 // 传递的resourceloader为null 4 this.resourceload竞争对手英语er = resourceloader; 5 asrt.notnull(primarysources, "primarysources must not be null"); 6 // 记录主方法的配置类名称 7 this.primarysources = new linkedhasht<>(arrays.aslist(primarysources)); 8 // 记录当前项目的类型 9 this.webapplicationtype = webapplicationtype.deducefromclasspath();10 // 加载配置在spring.factories文件中的applicationcontextinitializer对应的类型并实例化11 // 并将加载的数据存储在了 initializers 成员变量中。12 tinitializers((collection) getspringfactoriesinstances(applicationcontextinitializer.class));13 // 初始化监听器 并将加载的监听器实例对象存储在了listeners成员变量中14 tlisteners((collection) getspringfactoriesinstances(applicationlistener.class));15 // 反推main方法所在的class对象 并记录在了mainapplicationclass对象中16 this.mainapplicationclass = deducemainapplicationclass();17 }
首先来看下webapplicationtype是如何来推导出当前启动的项目的类型。通过代码可以看到是通过deducefromclasspath()方法根据classpath来推导出来的。
1this.webapplicationtype = webapplicationtype.deducefromclasspath();
跟踪进去看代码
在看整体的实现逻辑之前,我们先分别看两个内容,第一就是在上面的代码中使用到了相关的静态变量。
image.png
这些静态变量其实就是一些绑定的java类的全类路径。第二个就是 classutils.isprent()方法,该方法的逻辑也非常简单,就是通过反射的方式获取对应的类型的class对象,如果存在返回true,否则返回fal
image.png
所以到此推导的逻辑就非常清楚了
image.png
然后我们再来看下如何实现加载初始化器的。
1// 加载配置在spring.factories文件中的applicationcontextinitializer对应的类型并实例化2 // 并将加载的数据存储在了 initializers 成员变量中。3 tinitializers((collection) getspringfactoriesinstances(applicationcontextinitializer.class));
首先所有的初始化器都实现了
applicationcontextinitializer接口,也就是根据这个类型来加载相关的实现类。
然后加载的关键方法是
getspringfactoriesinstances()方法。该方法会加载 spring.factories文件中的key为
org.springframework.context.applicationcontextinitializer 的值。
spring-boot项目下
1# application context initializers2org.springframework.context.applicationcontextinitializer=3org.springframework.boot.context.configurationwarningsapplicationcontextinitializer,4org.springframework.boot.context.contextidapplicationcontextinitializer,5org.springframework.boot.context.config.delegatingapplicationcontextinitializer,6org.springframework.boot.rsocket.context.rsocketportinfoapplicationcontextinitializer,7org.springframework.boot.web.context.rverportinfoapplicationcontextinitializer
spring-boot-autoconfigure项目下
1高考语文题# initializers2org.springframework.context.applicationcontextinitializer=3org.springframework.boot.autoconfigure.sharedmetadatareaderfactorycontextinitializer,4org.梦见下雪了是什么预兆springframework.boot.autoconfigure.logging.conditionevaluationreportlogginglistener
image.png
先进入
springfactoriesloader.loadfactorynames(type, classloader)中具体查看加载文件的过程.
image.png
然后我们来看下 loadspringfactories方法
image.png
通过debug的方式查看会更清楚哦
image本科考试时间.png
通过 loadspringfactories 方法我们看到把 spring.factories文件中的所有信息都加载到了内存中了,但是我们现在只需要加载
applicationcontextinitializer类型的数据。这时我们再通过 getordefault()方法来查看。
image.png
进入方法中查看
image.png
然后会根据反射获取对应的实例对象。
image.png
image.png
好了到这其实我们就清楚了
getspringfactoriesinstances方法的作用就是帮我们获取定义在 meta-inf/spring.factories文件中的可以为
applicationcontextinitializer 的值。并通过反射的方式获取实例对象。然后把实例的对象信息存储在了springapplication的 initializers属性中。
image.png
清楚了 tinitializers()方法的作用后,再看 tlisteners()方法就非常简单了,都是调用了
getspringfactoriesinstances方法,只是传入的类型不同。也就是要获取的 meta-inf/spring.factories文件中定义的不同信息罢了。
image.png
即加载定义在 meta-inf/spring.factories文件中声明的所有的监听器,并将获取后的监听器存储在了 springapplication的 listeners属性中。
image.png
默认加载的监听器为:
image.png
最后我们来看下
duducemainapplicaitonclass()方法历届欧冠四强是如何反推导出main方法所在的class对象的。通过源码我们可以看到是通过 stacktrace来实现的。
1stacktrace:
2我们在学习函数调用时,都知道每个函数都拥有自己的栈空间。
3一个函数被调用时,就创建一个新的栈空间。那么通过函数的嵌套调用最后就形成了一个函数调用堆栈
stacktrace其实就是记录了程序方法执行的链路。通过debug方式可以更直观的来呈现。
image.png
那么相关的调用链路我们都可以获取到,剩下的就只需要获取每链路判断执行的方法名称是否是 main就可以了。
image.png
好了到此相关的4个核心步骤就给大家分析完了,希望对大家能有所帮助哦!
本文发布于:2023-04-05 05:38:32,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/8bdc02d34046f01dc706751e8cb120e7.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:springboot源码怎么看(springboot源码深度解析).doc
本文 PDF 下载地址:springboot源码怎么看(springboot源码深度解析).pdf
留言与评论(共有 0 条评论) |