知識庫 / Spring / Spring Boot RSS 訂閱

Spring Boot:repackage 與 Maven 包的差異

Maven,Spring Boot
HongKong
5
12:43 PM · Dec 06 ,2025

1. 概述

Apache Maven 是一個廣泛使用的項目依賴管理工具和項目構建工具。

在過去幾年中,Spring Boot 已經成為構建應用程序的相當流行的框架。 此外,還有 Spring Boot Maven 插件,它為 Apache Maven 提供 Spring Boot 支持。

我們知道,當我們使用 Maven 將應用程序打包為 JAR 或 WAR 歸檔文件時,可以使用 <em>mvn package</em>。 但是,Spring Boot Maven 插件包含一個 <em>repackage</em> 目標,並且它也作為 <em>mvn</em> 命令調用。

有時,這兩個 <em>mvn</em> 命令可能會讓人感到困惑。 在本教程中,我們將討論 <em>mvn package</em><em>spring-boot:repackage</em> 之間的區別。

2. 一個 Spring Boot 應用示例

首先,我們將創建一個簡單的 Spring Boot 應用作為示例:

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

為了驗證我們的應用程序是否正常運行,讓我們創建一個簡單的 REST 端點:

@RestController
public class DemoRestController {
    @GetMapping(value = "/welcome")
    public ResponseEntity welcomeEndpoint() {
        return ResponseEntity.ok("Welcome to Baeldung Spring Boot Demo!");
    }
}

3. Maven 的 package 目標

我們需要 spring-boot-starter-web 依賴項來構建我們的 Spring Boot 應用程序:

<artifactId>spring-boot-artifacts-2</artifactId>
<packaging>jar</packaging>
...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
...

Maven 的<em>package</em> 目標會將編譯後的代碼打包成其可分發的格式,在此情況下是 JAR 格式:

$ mvn package
[INFO] Scanning for projects...
[INFO] ------< com.baeldung.spring-boot-modules:spring-boot-artifacts-2 >------
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
 ... 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 ---
[INFO] Building jar: /home/kent ... /target/spring-boot-artifacts-2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
 ...

在執行 mvn package 命令後,我們可以找到構建好的 JAR 文件 spring-boot-artifacts-2.jar 位於 target 目錄下。 讓我們檢查一下創建的 JAR 文件的內容:

$ jar tf target/spring-boot-artifacts-2.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/baeldung/
com/baeldung/demo/
application.yml
com/baeldung/demo/DemoApplication.class
com/baeldung/demo/DemoRestController.class
META-INF/maven/...

如上輸出所示,由 mvn package 命令創建的 JAR 文件僅包含我們項目源代碼中的資源和編譯後的 Java 類。

我們可以將此 JAR 文件用作另一個項目中的依賴項。但是,即使它是 Spring Boot 應用程序,我們也不能使用 java -jar JAR_FILE 命令執行該 JAR 文件。這是因為運行時依賴項未打包。例如,我們沒有servlet容器來啓動web上下文。

要使用簡單的 java -jar 命令啓動我們的 Spring Boot 應用程序,我們需要構建一個“胖” JAR 文件。Spring Boot Maven 插件可以幫助我們完成此操作。

4. Spring Boot Maven 插件的 repackage 目標

現在,讓我們來了解 spring-boot:repackage 目標的作用。

4.1. 添加 Spring Boot Maven 插件

要執行 repackage 目標,我們需要在 pom.xml 中添加 Spring Boot Maven 插件:

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

4.2. 執行 spring-boot:repackage 目標

現在,讓我們清理之前構建的 JAR 文件,並嘗試執行 spring-boot:repackage 目標:

$ mvn clean spring-boot:repackage     
 ...
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
...
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) 
on project spring-boot-artifacts-2: Execution default-cli of goal 
org.springframework.boot:spring-boot-maven-plugin:2.3.3.RELEASE:repackage failed: Source file must not be null -> [Help 1]
...

哎呀,它不起作用。這是因為 spring-boot:repackage 目標會把現有的 JAR 或 WAR 歸檔文件作為源文件,並將整個項目運行時依賴項一起打包到最終的歸檔文件中。 這樣,重新打包的歸檔文件就可以使用命令行 java -jar JAR_FILE.jar 運行。

因此,在執行 spring-boot:repackage 目標之前,我們需要先構建 JAR 文件。

$ mvn clean package spring-boot:repackage
 ...
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
 ...
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-artifacts-2 ---
[INFO] Building jar: /home/kent/.../target/spring-boot-artifacts-2.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default-cli) @ spring-boot-artifacts-2 ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
 ...

4.3. 重打包 JAR 文件的內容

現在,如果我們在 target 目錄中檢查,我們會看到重打包的 JAR 文件和原始的 JAR 文件:

$ ls -1 target/*jar*
target/spring-boot-artifacts-2.jar
target/spring-boot-artifacts-2.jar.original

讓我們檢查重新打包的 JAR 文件內容:

$ jar tf target/spring-boot-artifacts-2.jar 
META-INF/
META-INF/MANIFEST.MF
 ...
org/springframework/boot/loader/JarLauncher.class
 ...
BOOT-INF/classes/com/baeldung/demo/
BOOT-INF/classes/application.yml
BOOT-INF/classes/com/baeldung/demo/DemoApplication.class
BOOT-INF/classes/com/baeldung/demo/DemoRestController.class
META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.xml
META-INF/maven/com.baeldung.spring-boot-modules/spring-boot-artifacts-2/pom.properties
BOOT-INF/lib/
BOOT-INF/lib/spring-boot-starter-web-2.3.3.RELEASE.jar
...
BOOT-INF/lib/spring-boot-starter-tomcat-2.3.3.RELEASE.jar
BOOT-INF/lib/tomcat-embed-core-9.0.37.jar
BOOT-INF/lib/jakarta.el-3.0.3.jar
BOOT-INF/lib/tomcat-embed-websocket-9.0.37.jar
BOOT-INF/lib/spring-web-5.2.8.RELEASE.jar
...
BOOT-INF/lib/httpclient-4.5.12.jar
...

如果檢查上面的輸出,它比由 mvn package 命令構建的 JAR 文件要長得多。

在這裏,在重新打包的 JAR 文件中,我們不僅包含來自我們項目的編譯後的 Java 類,還包括啓動我們的 Spring Boot 應用程序所需的全部運行時庫。例如,嵌入式 tomcat 庫被打包到 BOOT-INF/lib 目錄中。

接下來,讓我們啓動應用程序並檢查它是否正常工作。

$ java -jar target/spring-boot-artifacts-2.jar 
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

2020-12-22 23:36:32.704  INFO 115154 [main] com.baeldung.demo.DemoApplication      : Starting DemoApplication on YK-Arch with PID 11515...
...
2020-12-22 23:36:34.070  INFO 115154 [main] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8080 (http) ...
2020-12-22 23:36:34.078  INFO 115154 [main] com.baeldung.demo.DemoApplication      : Started DemoApplication in 1.766 seconds ...

我們的 Spring Boot 應用程序已啓動並運行。現在,讓我們通過調用我們的 welcome</em/> 終點驗證它:

$ curl http://localhost:8080/welcome
Welcome to Baeldung Spring Boot Demo!

太棒了!我們收到了預期的響應。我們的應用程序正在正常運行。

4.4. 執行 spring-boot:repackage 目標在 Maven 包構建生命週期中

我們可以配置 Spring Boot Maven 插件,在 Maven 的 package 階段對 Artifact 進行重新打包。換句話説,當執行 mvn package 時,spring-boot:repackage 將會自動執行。

配置非常簡單,我們只需將 repackage 目標添加到 execution 元素中:

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

現在,讓我們再次運行 mvn clean package

$ mvn clean package
 ...
[INFO] Building spring-boot-artifacts-2 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (default) @ spring-boot-artifacts-2 ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
 ...

輸出顯示 repackage 目標已執行。如果檢查文件系統,將會發現 repackaged JAR 文件已創建:

$ ls -lh target/*jar*
-rw-r--r-- 1 kent kent  29M Dec 22 23:56 target/spring-boot-artifacts-2.jar
-rw-r--r-- 1 kent kent 3.6K Dec 22 23:56 target/spring-boot-artifacts-2.jar.original

5. 結論

在本文中,我們討論了 mvn packagespring-boot:repackage 之間的區別。

此外,我們學習瞭如何在 Maven 生命週期中的 package 階段執行 spring-boot:repackage 命令。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.