打包可執行歸檔
該外掛可以建立可執行的歸檔檔案(jar 檔案和 war 檔案),這些檔案包含應用程式的所有依賴項,然後可以使用 java -jar 執行。
打包可執行歸檔檔案由 repackage 目標執行,如以下示例所示:
<build>
<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>
repackage 目標不應單獨在命令列上使用,因為它操作由 package 階段生成的源 jar(或 war)。要在命令列上使用此目標,您必須包含 package 階段:mvn package spring-boot:repackage。 |
如果您正在使用 spring-boot-starter-parent,則此執行已透過 repackage 執行 ID 預先配置,因此只需新增外掛定義。 |
上面的示例重新打包了在 Maven 生命週期打包階段構建的 jar 或 war 歸檔檔案,包括專案中定義的任何 provided 依賴項。如果需要排除其中一些依賴項,可以使用其中一個 exclude 選項;有關詳細資訊,請參閱依賴項排除。
原始(即不可執行)工件預設重新命名為 .original,但也可以使用自定義分類器保留原始工件。
maven-war-plugin 的 outputFileNameMapping 功能目前不受支援。 |
spring-boot-devtools 和 spring-boot-docker-compose 模組預設情況下會自動排除(您可以使用 excludeDevtools 和 excludeDockerCompose 屬性控制此行為)。為了使其與 war 打包一起使用,spring-boot-devtools 和 spring-boot-docker-compose 依賴項必須設定為 optional 或 provided 範圍。
該外掛會重寫您的清單檔案,特別是它會管理 Main-Class 和 Start-Class 條目。如果預設值不起作用,您必須在 Spring Boot 外掛中配置這些值,而不是在 jar 外掛中。清單檔案中的 Main-Class 由 Spring Boot 外掛的 layout 屬性控制,如以下示例所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start.class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
layout 屬性預設為由歸檔型別(jar 或 war)決定的值。以下佈局可用:
-
JAR:常規可執行 JAR 佈局。 -
WAR:可執行 WAR 佈局。provided依賴項放置在WEB-INF/lib-provided中,以避免在war部署到 Servlet 容器時發生衝突。 -
ZIP(別名DIR):類似於使用PropertiesLauncher的JAR佈局。 -
NONE:捆綁所有依賴項和專案資源。不捆綁引導載入程式。
分層 Jar 或 War
重新打包的 jar 分別在 BOOT-INF/classes 和 BOOT-INF/lib 中包含應用程式的類和依賴項。類似地,可執行 war 在 WEB-INF/classes 中包含應用程式的類,在 WEB-INF/lib 和 WEB-INF/lib-provided 中包含依賴項。對於需要從 jar 或 war 的內容構建 docker 映象的情況,能夠進一步分離這些目錄以便將它們寫入不同的層是很有用的。
分層歸檔檔案使用與常規重新打包的 jar 或 war 相同的佈局,但包含一個描述每個層的附加元資料檔案。
預設情況下,定義了以下層:
-
dependencies用於版本不包含SNAPSHOT的任何依賴項。 -
spring-boot-loader用於載入器類。 -
snapshot-dependencies用於版本包含SNAPSHOT的任何依賴項。 -
application用於本地模組依賴項、應用程式類和資源。
模組依賴項透過檢視當前構建中的所有模組來識別。如果模組依賴項只能透過將其安裝到 Maven 的本地快取中來解決,並且它不是當前構建的一部分,則它將被識別為常規依賴項。
層的順序很重要,因為它決定了當應用程式的一部分更改時,先前層被快取的可能性。預設順序是 dependencies、spring-boot-loader、snapshot-dependencies、application。最不可能更改的內容應首先新增,然後是更可能更改的層。
重新打包的歸檔檔案預設包含 layers.idx 檔案。要停用此功能,您可以按以下方式操作:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>false</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
自定義層配置
根據您的應用程式,您可能希望調整層的建立方式並新增新層。這可以透過單獨的配置檔案完成,該檔案應按如下所示註冊:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
<configuration>${project.basedir}/src/layers.xml</configuration>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置檔案描述瞭如何將歸檔檔案分成層以及這些層的順序。以下示例顯示瞭如何明確定義上述預設順序:
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-4.0.xsd">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
</into>
<into layer="application" />
</application>
<dependencies>
<into layer="application">
<includeModuleDependencies />
</into>
<into layer="snapshot-dependencies">
<include>*:*:*SNAPSHOT</include>
</into>
<into layer="dependencies" />
</dependencies>
<layerOrder>
<layer>dependencies</layer>
<layer>spring-boot-loader</layer>
<layer>snapshot-dependencies</layer>
<layer>application</layer>
</layerOrder>
</layers>
layers XML 格式定義為三個部分:
-
<application>塊定義了應用程式類和資源應如何分層。 -
<dependencies>塊定義了依賴項應如何分層。 -
<layerOrder>塊定義了層的寫入順序。
巢狀的 <into> 塊在 <application> 和 <dependencies> 部分中使用,用於宣告層的內容。塊按照它們定義的順序從上到下進行評估。任何未被早期塊宣告的內容仍可供後續塊考慮。
<into> 塊使用巢狀的 <include> 和 <exclude> 元素來宣告內容。<application> 部分使用 Ant 風格的路徑匹配進行包含/排除表示式。<dependencies> 部分使用 group:artifact[:version] 模式。它還提供 <includeModuleDependencies /> 和 <excludeModuleDependencies /> 元素,可用於包含或排除本地模組依賴項。
如果未定義 <include>,則所有內容(未被早期塊宣告的內容)都將被考慮。
如果未定義 <exclude>,則不應用任何排除。
檢視上面的 <dependencies> 示例,我們可以看到第一個 <into> 將為 application.layer 宣告所有模組依賴項。下一個 <into> 將為 snapshot-dependencies 層宣告所有 SNAPSHOT 依賴項。最後一個 <into> 將為 dependencies 層宣告剩餘的所有內容(在這種情況下,任何不是 SNAPSHOT 的依賴項)。
<application> 塊具有相似的規則。首先為 spring-boot-loader 層宣告 org/springframework/boot/loader/** 內容。然後為 application 層宣告任何剩餘的類和資源。
<into> 塊的定義順序通常與層的寫入順序不同。因此,<layerOrder> 元素必須始終包含,並且必須覆蓋 <into> 塊引用的所有層。 |
spring-boot:repackage
org.springframework.boot:spring-boot-maven-plugin:4.0.0
重新打包現有的 JAR 和 WAR 歸檔檔案,以便它們可以使用 java -jar 從命令列執行。使用 layout=NONE 也可以簡單地用於打包帶有巢狀依賴項(且沒有主類,因此不可執行)的 JAR。
可選引數
| 名稱 | 型別 | 預設值 |
|---|---|---|
|
|
|
|
||
|
|
|
|
|
|
|
||
|
||
|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
|
|
||
|
|
引數詳情
attach
將重新打包的歸檔檔案附加到本地 Maven 倉庫中安裝或部署到遠端倉庫。如果未配置分類器,它將替換正常的 jar。如果已配置分類器,使得正常的 jar 和重新打包的 jar 不同,它將與正常的 jar 一起附加。當屬性設定為 false 時,重新打包的歸檔檔案將不會被安裝或部署。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
classifier
新增到重新打包歸檔檔案的分類器。如果未給出,則主工件將被重新打包的歸檔檔案替換。如果給出,分類器還將用於確定要重新打包的源歸檔檔案:如果已存在具有該分類器的工件,它將被用作源並替換。如果不存在此類工件,則主工件將用作源,重新打包的歸檔檔案將作為帶有該分類器的補充工件附加。附加工件允許將其與原始工件一起部署,有關詳細資訊,請參閱 Maven 文件。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDevtools
從重新打包的歸檔檔案中排除 Spring Boot 開發工具。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDockerCompose
從重新打包的歸檔檔案中排除 Spring Boot 開發服務。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeGroupIds
要排除的 groupId 名稱的逗號分隔列表(精確匹配)。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludes
要排除的 artifact 定義集合。Exclude 元素定義了強制的 groupId 和 artifactId 元件以及可選的 classifier 元件。當配置為屬性時,值應以逗號分隔,元件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
includes
要包含的 artifact 定義集合。Include 元素定義了強制的 groupId 和 artifactId 元件以及可選的 classifier 元件。當配置為屬性時,值應以逗號分隔,元件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
layout
歸檔檔案的型別(對應於其內部依賴項的佈局方式)。可能的值為 JAR、WAR、ZIP、DIR、NONE。預設為根據歸檔型別推斷的值。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputDirectory
包含生成的歸檔檔案的目錄。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputTimestamp
可重現輸出歸檔條目的時間戳,格式可以是 ISO 8601 (yyyy-MM-dd’T’HH:mm:ssXXX) 或表示自紀元以來的秒數的 int。
名稱 |
|
|---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
示例
自定義分類器
預設情況下,repackage 目標將原始工件替換為重新打包的工件。對於表示應用程式的模組來說,這是一個合理的行為,但如果您的模組用作另一個模組的依賴項,您需要為重新打包的工件提供一個分類器。原因是應用程式類被打包在 BOOT-INF/classes 中,因此依賴模組無法載入重新打包的 jar 的類。
如果出現這種情況,或者如果您希望保留原始工件並使用不同的分類器附加重新打包的工件,請按以下示例配置外掛:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
如果您正在使用 spring-boot-starter-parent,則 repackage 目標將自動以 ID 為 repackage 的執行方式執行。在這種設定下,只需指定配置即可,如以下示例所示:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置將生成兩個工件:原始工件和由 repackage 目標生成的重新打包工件。兩者都將透明地安裝/部署。
您也可以使用相同的配置,如果您想以替換主工件的方式重新打包輔助工件。以下配置將安裝/部署一個帶有重新打包應用程式的單個 task 分類工件:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
由於 maven-jar-plugin 和 spring-boot-maven-plugin 在同一階段執行,因此 jar 外掛必須首先定義(以便在 repackage 目標之前執行)。同樣,如果您使用 spring-boot-starter-parent,這可以簡化如下:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
自定義名稱
如果您需要重新打包的 jar 具有與專案 artifactId 屬性定義的名稱不同的本地名稱,請使用標準的 finalName,如以下示例所示:
<project>
<build>
<finalName>my-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置將在 target/my-app.jar 中生成重新打包的工件。
本地重新打包工件
預設情況下,repackage 目標會將原始工件替換為可執行工件。如果您只需要部署原始 jar,但又希望能夠使用常規檔名執行您的應用程式,請按如下方式配置外掛:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置生成兩個工件:原始工件和由 repackage 目標生成的可執行工件。只有原始工件會被安裝/部署。
自定義佈局
Spring Boot 使用在附加 jar 檔案中定義的自定義佈局工廠重新打包此專案的 jar 檔案,該檔案作為構建外掛的依賴項提供:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<layoutFactory implementation="com.example.CustomLayoutFactory">
<customProperty>value</customProperty>
</layoutFactory>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-layout</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
佈局工廠作為 LayoutFactory(來自 spring-boot-loader-tools)的實現提供,並在 pom 中明確指定。如果外掛類路徑上只有一個自定義 LayoutFactory 並且它列在 META-INF/spring.factories 中,則無需在外掛配置中顯式設定它。
如果設定了顯式 layout,則始終忽略佈局工廠。
依賴項排除
預設情況下,repackage 和 run 目標都將包含專案中定義的任何 provided 依賴項。Spring Boot 專案應將 provided 依賴項視為執行應用程式所需的“容器”依賴項。通常來說,Spring Boot 專案不被用作依賴項,因此不太可能擁有任何 optional 依賴項。當專案確實有可選依賴項時,它們也將被 repackage 和 run 目標包含。
其中一些依賴項可能根本不需要,並且應從可執行 jar 中排除。為保持一致性,在執行應用程式時也不應包含它們。
有兩種方法可以從打包/執行時排除依賴項:
-
排除由
groupId和artifactId標識的特定工件,如果需要,可選地帶有classifier。 -
排除屬於給定
groupId的任何工件。
以下示例排除 com.example:module1,且僅排除該工件:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>com.example</groupId>
<artifactId>module1</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
此示例排除了屬於 com.example 組的任何工件:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeGroupIds>com.example</excludeGroupIds>
</configuration>
</plugin>
</plugins>
</build>
</project>
JAR 工具
當建立分層 jar 或 war 時,spring-boot-jarmode-tools jar 將作為依賴項新增到您的歸檔檔案中。透過將此 jar 放在類路徑上,您可以在特殊模式下啟動您的應用程式,該模式允許引導程式碼執行與您的應用程式完全不同的東西,例如,提取層的程式碼。如果您希望排除此依賴項,可以按以下方式操作:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeTools>false</includeTools>
</configuration>
</plugin>
</plugins>
</build>
</project>
自定義層配置
預設設定將依賴項分為快照和非快照,但是,您可能有更復雜的規則。例如,您可能希望將專案中的公司特定依賴項隔離到專用層中。以下 layers.xml 配置顯示了這樣一種設定:
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-4.0.xsd">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
</into>
<into layer="application" />
</application>
<dependencies>
<into layer="snapshot-dependencies">
<include>*:*:*SNAPSHOT</include>
</into>
<into layer="company-dependencies">
<include>com.acme:*</include>
</into>
<into layer="dependencies"/>
</dependencies>
<layerOrder>
<layer>dependencies</layer>
<layer>spring-boot-loader</layer>
<layer>snapshot-dependencies</layer>
<layer>company-dependencies</layer>
<layer>application</layer>
</layerOrder>
</layers>
上述配置建立了一個額外的 company-dependencies 層,其中包含所有 com.acme groupId 的庫。