Spring Boot使用系列四(启动之前和启动之后)

本文主要探讨了Spring Boot在main方法执行完毕后为何仍能运行,原因是启动了一个非守护线程来保持应用运行。此外,文章还介绍了Spring Boot在main方法之前如何启动,包括在IDEA中直接启动和通过jar包启动的方式,并分析了jar包的内部结构。通过对源码的分析,揭示了Spring Boot启动流程的关键步骤,如创建ClassLoader和启动Spring Boot应用。
摘要由CSDN通过智能技术生成

在前面两篇的文章中我们分析了从Main开始的启动过程ApplicationContext的刷新过程

1. 这还有一个小小的疑问:main函数都运行为了,为什么spring boot还能够运行呢?

针对这个问题,我们转换一下思路,为什么spring boot应用程序还在运行,那是因为jvm还没有推出,那什么情况下jvm会退出呢?

我们都知道: System.exit()Runtime.exit()可以直接导致当前JVM退出。还有一种情况就是所有的非daemon进程完全终止

那么我们可不可以猜测Spring Boot还能够继续运行的原因是由于还有非daemon进程没有终止

那我们用jstack分析一下一个启动的spring boot线程 jstack 9818 |grep tid |grep -v daemon
在我的电脑上能够看到如下信息:
排除掉其中的GC和JVM线程,我们发现了一个奇怪的线程server,那我们看一下server的详细信息呢?
在这里插入图片描述看到这么我们注意到最后一行NettyWebServer.run方法,我们跟进代码按一下这里面是什么呢?在这里插入图片描述在此我们找到了我们用jstack看到的server线程的由来,通过方法名startDaemonAwaitThread可以知道我们启动一个非daemon的线程来等待关闭spring boot线程。这就是为什么main方法运行完了,spring boot程序还能欧股继续运行的原因。

扩展一下,因为我的程序是基于spring cloud gateway的,底层是用户netty实现的nio。所以这个会进入NettyWebServer。如果是一般基于tomcat的会进入TomcatWebServer,tomcat也有相应的代码:
在这里插入图片描述在那怎么确实用户netty还是Tomcat或者undertow等webServer呢?从前面的启动过程中我们看到有这样的代码

	static WebApplicationType deduceFromClasspath() {
   
		if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值