现象
启动一个spring boot项目很奇怪,启动之后,立即就断掉链接。具体报错如下:
2022-02-22 14:32:58.486 INFO 44464 --- [ main] c.e.t.TradeServerServiceApplication : The following profiles are active: dev
2022-02-22 14:32:58.833 INFO 44464 --- [ main] c.e.t.TradeServerServiceApplication : Started TradeServerServiceApplication in 0.607 seconds (JVM running for 1.155)
Disconnected from the target VM, address: '127.0.0.1:64482', transport: 'socket'

对这个问题,百思不得其解,于是决定跟踪源码查看一下究竟。
排查思路
在代码跟踪到
this.webApplicationType = WebApplicationType.deduceFromClasspath();
这行的时候,发现推断出来的,webApplicationType是NONE,为什么是NONE哪?我启动的是web项目。所以推断出一定出现问题在这行代码。

于是跟进这行代码,去研究一下究竟?
发现webApplicationType有三种类型,分别为NONE、SERVLET、REACTIVE。

根据解释
NONE:不是web应用项目,不应该启动一个web服务。
SERVLET: 是和NONE相对的,是web项目。
REACTIVE:是一种交互的web项目,这个没用过这种项目,具体理解不多。
在看一下推断代码如下:

逻辑如下:
- reactive
路径包含org.springframework.web.reactive.DispatcherHandler,并且不包含org.springframework.web.servlet.DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer - none
不是reactive,并且路径中没有javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext - servlet
剩余的部分都是servlet
具体推断落到具体代码为ClassUtils.isPresent上,我们看一下这个代码的源码

forName代码逻辑很简单,就是在当前类加载器能加载的情况下,返回true,不能加载的情况下,返回false。

所以只要启动的当前目录下,能找到这个类,那么就能加载,找不到就不能加载,由此,推断是缺少了(
"javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext"
) 这两个类、接口,所以推断缺少包,于是引入了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
包,问题得到解决
总结
1.springboot 帮我们快捷建立项目,导致我们忽略了很多细节,我们还是要明白整个过程是怎么加载,运行的,不然出现问题,不跟源码,很难解决的。
本文记录了一位开发者在启动SpringBoot项目时遇到的奇怪问题,即项目启动后立即断开连接。经过排查,发现在推断webApplicationType时,结果为NONE,而非预期的SERVLET。通过深入源码,发现是因为缺少特定类导致。解决方案是引入`spring-boot-starter-web`依赖。作者强调理解项目加载和运行过程的重要性,以便于更好地解决问题。

被折叠的 条评论
为什么被折叠?



