springboot源码怎么看_springboot源码深度解析

springboot源码怎么看_springboot源码深度解析,第1张

springboot源码怎么看_springboot源码深度解析 前面给大家介绍了SpringBoot启动的核心流程,本文开始给大家详细的来介绍SpringBoot启动中的具体实现的相关细节。

SpringBoot2.pngSpringApplication构造器  首先我们来看下在SpringApplication的构造方法中是如何帮我们完成这4个核心 *** 作的。

image.png 1 @SuppressWarnings({ "unchecked", "rawtypes" }) 2 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { 3 // 传递的resourceLoader为null 4 this.resourceLoader = resourceLoader; 5 Assert.notNull(primarySources, "PrimarySources must not be null"); 6 // 记录主方法的配置类名称 7 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); 8 // 记录当前项目的类型 9 this.webApplicationType = WebApplicationType.deduceFromClasspath();10 // 加载配置在spring.factories文件中的ApplicationContextInitializer对应的类型并实例化11 // 并将加载的数据存储在了 initializers 成员变量中。

12 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));13 // 初始化监听器 并将加载的监听器实例对象存储在了listeners成员变量中14 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));15 // 反推main方法所在的Class对象 并记录在了mainApplicationClass对象中16 this.mainApplicationClass = deduceMainApplicationClass();17 }1.webApplicationType  首先来看下webApplicationType是如何来推导出当前启动的项目的类型。

通过代码可以看到是通过deduceFromClassPath()方法根据ClassPath来推导出来的。

1this.webApplicationType = WebApplicationType.deduceFromClasspath();  跟踪进去看代码在看整体的实现逻辑之前,我们先分别看两个内容,第一就是在上面的代码中使用到了相关的静态变量。

image.png  这些静态变量其实就是一些绑定的Java类的全类路径。

第二个就是 ClassUtils.isPresent()方法,该方法的逻辑也非常简单,就是通过反射的方式获取对应的类型的Class对象,如果存在返回true,否则返回falseimage.png  所以到此推导的逻辑就非常清楚了image.png2.setInitializers  然后我们再来看下如何实现加载初始化器的。

1// 加载配置在spring.factories文件中的ApplicationContextInitializer对应的类型并实例化2 // 并将加载的数据存储在了 initializers 成员变量中。

3 setInitializers((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.ServerPortInfoApplicationContextInitializerspring-boot-autoconfigure项目下1# Initializers2org.springframework.context.ApplicationContextInitializer=3org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,4org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListenerimage.png具体的加载方法为 `getSpringFacotiesInstance()`方法,我们进入查看  先进入SpringFactoriesLoader.loadFactoryNames(type, classLoader)中具体查看加载文件的过程.image.png  然后我们来看下 loadSpringFactories方法image.png  通过Debug的方式查看会更清楚哦image.png  通过 loadSpringFactories 方法我们看到把 spring.factories文件中的所有信息都加载到了内存中了,但是我们现在只需要加载ApplicationContextInitializer类型的数据。

这时我们再通过 getOrDefault()方法来查看。

image.png  进入方法中查看image.png  然后会根据反射获取对应的实例对象。

image.pngimage.png  好了到这其实我们就清楚了getSpringFactoriesInstances方法的作用就是帮我们获取定义在 META-INF/spring.factories文件中的可以为ApplicationContextInitializer 的值。

并通过反射的方式获取实例对象。

然后把实例的对象信息存储在了SpringApplication的 initializers属性中。

image.png3.setListeners  清楚了 setInitializers()方法的作用后,再看 setListeners()方法就非常简单了,都是调用了getSpringFactoriesInstances方法,只是传入的类型不同。

也就是要获取的 META-INF/spring.factories文件中定义的不同信息罢了。

image.png  即加载定义在 META-INF/spring.factories文件中声明的所有的监听器,并将获取后的监听器存储在了 SpringApplication的 listeners属性中。

image.png  默认加载的监听器为:image.png4.mainApplicationClass  最后我们来看下duduceMainApplicaitonClass()方法是如何反推导出main方法所在的Class对象的。

通过源码我们可以看到是通过 StackTrace来实现的。

1StackTrace:2我们在学习函数调用时,都知道每个函数都拥有自己的栈空间。

3一个函数被调用时,就创建一个新的栈空间。

那么通过函数的嵌套调用最后就形成了一个函数调用堆栈  StackTrace其实就是记录了程序方法执行的链路。

通过Debug方式可以更直观的来呈现。

image.png  那么相关的调用链路我们都可以获取到,剩下的就只需要获取每链路判断执行的方法名称是否是 main就可以了。

image.png  好了到此相关的4个核心步骤就给大家分析完了,希望对大家能有所帮助哦!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/665565.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-18
下一篇 2022-04-18

发表评论

登录后才能评论

评论列表(0条)

保存