1. 概述

本教程将介绍在 Spring Boot 应用中通过 Maven 和 Gradle 定义入口点的多种方式。

Spring Boot 应用的主类是包含 public static void main() 方法的类,该方法负责启动 Spring ApplicationContext默认情况下,如果未显式指定主类,Spring 会在编译时搜索类路径,当找不到或找到多个主类时会导致启动失败。

与传统 Java 应用不同,本文讨论的主类不会作为 Main-Class 元数据属性出现在最终 JAR/WAR 文件的 META-INF/MANIFEST.MF 中。

Spring Boot 要求将构件的 Main-Class 属性设置为 org.springframework.boot.loader.JarLauncher(或 WarLauncher),这意味着直接通过 java 命令行传递主类无法正确启动应用。

示例清单文件如下:

Manifest-Version: 1.0
Start-Class: com.baeldung.DemoApplication
Main-Class: org.springframework.boot.loader.JarLauncher

我们需要在清单中定义 Start-Class 属性,该属性由 JarLauncher 解析以启动应用。下面介绍如何通过 Maven 和 Gradle 控制此属性。

2. Maven 配置

主类可通过以下两种方式定义:

方式一:在 pom.xml 属性中定义

<properties>
      <!-- 通过 "java -jar" 启动的主类 -->
      <start-class>com.baeldung.DemoApplication</start-class>
</properties>

⚠️ 注意:此配置仅在 pom.xml 中添加 spring-boot-starter-parent 作为父项目时生效。

方式二:在插件配置中定义

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>             
            <configuration>    
                <mainClass>com.baeldung.DemoApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

推荐:此方式更灵活,不依赖父项目继承。

完整 Maven 配置示例可参考 GitHub 仓库

3. Gradle 配置

使用 Spring Boot Gradle 插件时,可通过以下方式指定主类:

方式一:在 springBoot 配置块中定义

springBoot {
    mainClassName = 'com.baeldung.DemoApplication'
}

优点:同时影响 bootRunbootJar 任务。

方式二:在 bootJar 任务中定义

bootJar {
    mainClassName = 'com.baeldung.DemoApplication'
}

局限:仅影响生成的 JAR 文件,不影响 bootRun 等其他任务。

方式三:通过清单属性定义

bootJar {
    manifest {
        attributes 'Start-Class': 'com.baeldung.DemoApplication'
    }
}

方式四:全局属性定义(需应用 Gradle Application 插件)

mainClassName = 'com.baeldung.DemoApplication'

完整 Gradle 配置示例可参考 GitHub 仓库

4. 命令行指定

可通过 JVM 参数覆盖主类:

java -cp bootApp.jar -Dloader.main=com.baeldung.DemoApplication org.springframework.boot.loader.PropertiesLauncher

⚠️ 注意:此方式使用 PropertiesLauncher 而非默认的 JarLauncher

5. 多环境主类配置

在多环境(Profile)项目中,需为不同环境指定主类。

5.1. 问题场景

当项目包含多个带 @SpringBootApplication@Profile 的主类时,直接启动会报错:

$ mvn spring-boot:run \
-Dspring.profiles.active=errorhandling \
-Perrorhandling

# 错误输出摘要
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.1.5:run 
[ERROR] Unable to find a single main class from the following candidates 
[com.baeldung.favicon.FaviconApplication, ...] -> [Help 1]

原因:Spring 无法自动匹配当前 Profile 的主类。

5.2. 解决方案

pom.xml 中按 Profile 配置主类:

步骤一:定义 Profile 属性

<profiles>
    <profile>
        <id>errorhandling</id>
        <properties>
            <spring.boot.mainclass>com.baeldung.errorhandling.ErrorHandlingApplication</spring.boot.mainclass>
        </properties>
    </profile>
    <!-- 其他 Profile 配置 -->
</profiles>

步骤二:配置插件引用属性

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>${spring.boot.mainclass}</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

关键点:通过 ${spring.boot.mainclass} 动态绑定 Profile 属性。

5.3. 启动验证

执行带 Profile 的启动命令:

$ mvn spring-boot:run \
-Dspring.profiles.active=errorhandling \
-Perrorhandling

# 成功输出摘要
22:46:16.908 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 9000 (http)

结果:应用成功启动,使用指定 Profile 的主类。

6. 总结

配置 Spring Boot 主类的本质是修改 JAR/WAR 清单中的 Start-Class 属性。本文提供了多种实现方式:

  • Maven:通过 <start-class> 属性或插件配置
  • Gradle:通过 springBoot 配置块或任务属性
  • 命令行:使用 -Dloader.main 参数
  • 多环境:结合 Profile 和动态属性绑定

完整代码示例请参考:


原始标题:Spring Boot: Configuring a Main Class