1. Bug 简介

在本地使用 IDEA 启动 Spring Boot 应用时,控制台输出如下:

 . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.6.0) 2025-08-16 16:52:26.168 INFO 7220 --- [ main] c.z.g.center.ApiGatewayApplication : Starting ApiGatewayApplication using Java 1.8.0_361 on DESKTOP-RNEPHEV with PID 7220 (F:\zsbao\Code\IDE\buckstack_project\API-GateWay\api-gateway-center\api-gateway-ceneter-01\target\classes started by hp-pc in F:\zsbao\Code\IDE\buckstack_project\API-GateWay\api-gateway-center) 2025-08-16 16:52:26.171 INFO 7220 --- [ main] c.z.g.center.ApiGatewayApplication : No active profile set, falling back to default profiles: default 2025-08-16 16:52:26.798 INFO 7220 --- [ main] c.z.g.center.ApiGatewayApplication : Started ApiGatewayApplication in 0.841 seconds (JVM running for 1.299) 进程已结束,退出代码为 0

现象:应用正常初始化,但没有任何 Web 容器启动日志(如 Tomcat started on port ...),进程随即退出,退出码为 0。

2. 环境信息

  • JDK 版本:1.8.0_361

  • Spring Boot 版本:2.6.0

  • 项目打包方式war

  • 关键依赖

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
         <exclusions>
             <exclusion>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-starter-tomcat</artifactId>
             </exclusion>
         </exclusions>
     </dependency>
     
  • application.yml(简化版):

     server:
       port: 80
     spring:
       datasource:
         url: jdbc:mysql://127.0.0.1:13306/api_gateway
         username: root
         password: 123456
         driver-class-name: com.mysql.cj.jdbc.Driver
     

3. 根本原因分析

3.1 当前项目配置导致的主要原因

  1. 打包方式为 WAR

    • 项目 pom.xml 中指定 <packaging>war</packaging>

    • Spring Boot 的默认启动器是面向 JAR(可独立运行),而 WAR 通常需要外部容器(Tomcat、Jetty)来托管。

  2. 排除了内置 Tomcat 依赖

    • spring-boot-starter-web 中排除了 spring-boot-starter-tomcat

    • 导致应用中没有内置 Web 容器,运行 main() 时 Spring Boot 完成上下文初始化后直接退出。

这两个因素叠加,使得应用在本地调试时不会常驻运行。

3.2 其他可能导致类似现象的情况

  1. Web 模式被显式关闭

    • 配置文件中有: spring.main.web-application-type=none

    • 或者启动类里显式调用: new SpringApplicationBuilder(...).web(WebApplicationType.NONE);

  2. 排除了 Web 自动配置

    • 启动类上使用了: @SpringBootApplication(exclude = {WebMvcAutoConfiguration.class})

    • 导致 Spring Boot 没有启动 Web 环境。

  3. CommandLineRunnerApplicationRunner 主动调用 System.exit()

    • 若项目中有 Runner,在执行完成后显式调用 System.exit(0),也会出现“秒退”的情况。

  4. 主类未正确声明

    • @SpringBootApplication 注解缺失,或 SpringApplication.run(...) 传入的类不是启动类。

  5. 端口占用或权限问题

    • 配置了 server.port=80,在 Windows 下运行可能需要管理员权限,若绑定失败,可能导致进程退出。

  6. 依赖缺失或版本冲突

    • spring-boot-starter-web 缺失或和 spring-boot-starter-parent 版本不匹配。

    • 数据源配置错误时通常会报错,但也可能在没有任何 Web 容器时表现为秒退。

4. 解决方案

  • 将打包方式改为 JAR: <packaging>jar</packaging>

  • 保留内置 Tomcat:

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     
  • 启动后应看到: Tomcat started on port(s): 8080 ...

5. Bug 修复验证点

  1. 启动日志出现: Tomcat started on port(s): 8080 (http)

  2. 访问 http://localhost:8080(或配置的端口)返回正常响应。

  3. 进程常驻,不会退出。