现象
启动一个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 帮我们快捷建立项目,导致我们忽略了很多细节,我们还是要明白整个过程是怎么加载,运行的,不然出现问题,不跟源码,很难解决的。