You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

分离Main Class与非Main Class后Spring Boot应用无法启动问题

Spring Boot分离启动类与Controller启动失败问题及多应用切换测试方案

我想在同一个项目里测试多个Spring应用,但碰到了启动类(Main class)和主方法(Main method)相关的问题。

编写的RestController类

用于接收POST请求的Web API:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class restAPITest {

    @PostMapping("/example")
    public String handleExampleRequest(@RequestBody String requestData) {
        // 处理传入数据
        System.out.println("Received data: " + requestData);

        // 返回响应
        return "Data received successfully";
    }
}

单独的启动类

我创建了带main方法的mainClass来启动Spring应用:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class mainClass {
    public static void main(String[] args) {
        SpringApplication.run(restAPITest.class, args);
    }
}

启动错误信息

启动后出现如下错误:

Description:

Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.

Action:

Check your application's dependencies for a supported servlet web server.
Check the configured web application type

现象与疑问

项目里两个文件不在同一个目录下。如果把main方法放到restAPITest类里,应用能正常启动,但分离成两个类就不行。我搞不懂Spring Boot为什么不能分离main方法。

需求

我想要用下面这种形式的启动类,通过注释切换来逐个测试不同应用,不是同时启动多个:

public static void main(String[] args) {
        //SpringApplication.run(testSpringApp1.class, args);
        SpringApplication.run(testSpringApp2.class, args);
        //SpringApplication.run(testSpringApp3.class, args);
    }

问题原因及解决办法

1. 启动失败的核心原因

你在SpringApplication.run()里传入的是restAPITest.class,但这个类没有@SpringBootApplication注解,Spring Boot无法触发自动配置流程(包括Servlet Web服务器的自动配置)。而当你把main方法放到restAPITest里时,这个类同时拥有@RestController和@SpringBootApplication,所以能正常完成自动配置。

另外,Spring Boot默认从@SpringBootApplication所在类的包开始向下扫描组件,如果mainClass和restAPITest不在同一个包或子包下,即使启动类传入正确,也可能扫不到Controller。

2. 正确的分离写法

修改mainClass的main方法,传入自身(带有@SpringBootApplication的类),若Controller在不同包,需手动指定扫描路径:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

// 若restAPITest在其他包,添加scanBasePackages指定扫描路径
@SpringBootApplication(
    exclude = {DataSourceAutoConfiguration.class },
    scanBasePackages = "com.yourpackage.rest"
)
public class mainClass {
    public static void main(String[] args) {
        // 传入当前带@SpringBootApplication的启动类
        SpringApplication.run(mainClass.class, args);
    }
}

3. 多应用切换测试实现方案

要通过注释切换启动不同应用,需为每个测试应用单独创建带@SpringBootApplication的配置类,再在统一启动类中切换:

步骤1:创建多应用配置类

每个配置类指定专属的扫描包,确保只加载对应应用的组件:

// 测试应用1配置类
@SpringBootApplication(
    exclude = {DataSourceAutoConfiguration.class },
    scanBasePackages = "com.yourpackage.app1"
)
public class TestSpringApp1 {
}

// 测试应用2配置类
@SpringBootApplication(
    exclude = {DataSourceAutoConfiguration.class },
    scanBasePackages = "com.yourpackage.app2"
)
public class TestSpringApp2 {
}

步骤2:统一启动入口

public class MainLauncher {
    public static void main(String[] args) {
        // 切换注释即可启动不同应用
        // SpringApplication.run(TestSpringApp1.class, args);
        SpringApplication.run(TestSpringApp2.class, args);
        // SpringApplication.run(TestSpringApp3.class, args);
    }
}

额外注意事项

  • 每个应用配置类的扫描包要精准,避免组件冲突或漏扫
  • 不同测试应用需指定不同端口,可在各自的application.properties中配置:server.port=8081、server.port=8082
  • 若应用依赖差异大,可通过Maven/Gradle的Profile管理依赖,减少冗余

内容的提问来源于stack exchange,提问作者Hoang Minh Quang FX15045

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:10:16