SpringBoot源码分析之SpringApplication构造方法核心源码分析

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
this.webApplicationType = WebApplicationType.deduceFromClasspath();

跟踪进去看代码

static WebApplicationType deduceFromClasspath() {

if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)

&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)

&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {

return WebApplicationType.REACTIVE;

}

for (String className : SERVLET_INDICATOR_CLASSES) {

if (!ClassUtils.isPresent(className, null)) {

return WebApplicationType.NONE;

}

}

return WebApplicationType.SERVLET;

}

在看整体的实现逻辑之前,我们先分别看两个内容,第一就是在上面的代码中使用到了相关的静态变量。

image.png

这些静态变量其实就是一些绑定的Java类的全类路径。第二个就是 ClassUtils.isPresent()方法,该方法的逻辑也非常简单,就是通过反射的方式获取对应的类型的Class对象,如果存在返回true,否则返回false

image.png

所以到此推导的逻辑就非常清楚了

image.png

2.setInitializers


然后我们再来看下如何实现加载初始化器的。

// 加载配置在spring.factories文件中的ApplicationContextInitializer对应的类型并实例化

// 并将加载的数据存储在了 initializers 成员变量中。

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

首先所有的初始化器都实现了 ApplicationContextInitializer接口,也就是根据这个类型来加载相关的实现类。

public interface ApplicationContextInitializer {

void initialize(C var1);

}

然后加载的关键方法是 getSpringFactoriesInstances()方法。该方法会加载 spring.factories文件中的key为 org.springframework.context.ApplicationContextInitializer 的值。

spring-boot项目下

Application Context Initializers

org.springframework.context.ApplicationContextInitializer=\

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\

org.springframework.boot.context.ContextIdApplicationContextInitializer,\

org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\

org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\

org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

spring-boot-autoconfigure项目下

Initializers

org.springframework.context.ApplicationContextInitializer=\

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\

org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

image.png

具体的加载方法为 getSpringFacotiesInstance()方法,我们进入查看

private Collection getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object… args) {

// 获取当前上下文类加载器

ClassLoader classLoader = getClassLoader();

// 获取到的扩展类名存入set集合中防止重复

Set names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

// 创建扩展点实例

List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

AnnotationAwareOrderComparator.sort(instances);

return instances;

}

先进入 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

3.setListeners


清楚了 setInitializers()方法的作用后,再看 setListeners()方法就非常简单了,都是调用了 getSpringFactoriesInstances方法,只是传入的类型不同。也就是要获取的 META-INF/spring.factories文件中定义的不同信息罢了。

image.png

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

Java核心架构进阶知识点

面试成功其实都是必然发生的事情,因为在此之前我做足了充分的准备工作,不单单是纯粹的刷题,更多的还会去刷一些Java核心架构进阶知识点,比如:JVM、高并发、多线程、缓存、Spring相关、分布式、微服务、RPC、网络、设计模式、MQ、Redis、MySQL、设计模式、负载均衡、算法、数据结构、kafka、ZK、集群等。而这些也全被整理浓缩到了一份pdf——《Java核心架构进阶知识点整理》,全部都是精华中的精华,本着共赢的心态,好东西自然也是要分享的

image

image

image

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
,本着共赢的心态,好东西自然也是要分享的

[外链图片转存中…(img-hIrbSdrb-1714670467927)]

[外链图片转存中…(img-vBr9As50-1714670467927)]

[外链图片转存中…(img-wGh0bPxm-1714670467928)]

内容颇多,篇幅却有限,这就不在过多的介绍了,大家可根据以上截图自行脑补
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值