封裝可執行歸檔
此外掛程式可以建立包含應用程式所有依賴的可執行歸檔(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 生命週期的 package 階段建置的 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
範圍。
此外掛程式會重寫您的 manifest,尤其是它會管理 Main-Class
和 Start-Class
項目。如果預設值無法運作,您必須在 Spring Boot 外掛程式中設定值,而不是在 jar 外掛程式中。manifest 中的 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
layers-xsd: https://www.springframework.org/schema/boot/layers/layers-3.3.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>
區段對 include/exclude 運算式使用 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:3.3.5
重新封裝現有的 JAR 和 WAR 歸檔,使其可以使用 java -jar
從命令列執行。使用 layout=NONE
也可以僅用於封裝具有巢狀依賴關係(且沒有主類別,因此不可執行)的 JAR。
選用參數
名稱 | 類型 | 預設值 |
---|---|---|
|
|
|
|
||
|
||
|
||
|
|
|
|
|
|
|
||
|
||
|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
|
|
||
|
|
參數詳細資訊
attach
附加重新封裝的歸檔,以便安裝到您的本機 Maven 儲存庫或部署到遠端儲存庫。如果未設定分類器,它將取代正常的 jar。如果已設定 classifier
,使得正常的 jar 和重新封裝的 jar 不同,則它將與正常的 jar 一起附加。當屬性設定為 false
時,將不會安裝或部署重新封裝的歸檔。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
classifier
要新增到重新封裝歸檔的分類器。如果未給定,則主要工件將被重新封裝的歸檔取代。如果給定,分類器也將用於決定要重新封裝的來源歸檔:如果具有該分類器的工件已存在,則它將用作來源並被取代。如果不存在此類工件,則主要工件將用作來源,並且重新封裝的歸檔將作為具有該分類器的補充工件附加。附加工件允許將其與原始工件一起部署,請參閱Maven 文件以取得更多詳細資訊。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
embeddedLaunchScript
如果 jar 是完全可執行的,則要前置於 jar 前面的嵌入式啟動腳本。如果未指定,將使用「Spring Boot」預設腳本。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
embeddedLaunchScriptProperties
應在嵌入式啟動腳本中展開的屬性。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDevtools
從重新封裝的歸檔中排除 Spring Boot 開發工具。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDockerCompose
從重新封裝的歸檔中排除 Spring Boot 開發服務。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeGroupIds
要排除的 groupId 名稱的逗號分隔清單(完全比對)。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludes
要排除的工件定義集合。Exclude
元素定義了強制性的 groupId
和 artifactId
組件以及選用的 classifier
組件。當設定為屬性時,值應以逗號分隔,組件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
executable
透過在 jar 前面加上啟動腳本,為 *nix 機器建立完全可執行的 jar。<p> 目前,某些工具不接受此格式,因此您可能不一定能夠使用此技術。例如,jar -xf
可能會靜默地無法解壓縮已設為完全可執行的 jar 或 war。建議您僅在打算直接執行它,而不是使用 java -jar
執行它或將其部署到 servlet 容器時,才啟用此選項。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
includes
要包含的工件定義集合。Include
元素定義了強制性的 groupId
和 artifactId
組件以及選用的 classifier
組件。當設定為屬性時,值應以逗號分隔,組件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
layout
歸檔的類型(對應於依賴在其中配置的方式)。可能的值為 JAR
、WAR
、ZIP
、DIR
、NONE
。預設為根據歸檔類型猜測。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
layoutFactory
如果未設定明確的版面配置,則將用於建立可執行歸檔的版面配置工廠。替代版面配置實作可以由第三方提供。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
mainClass
主類別的名稱。如果未指定,將使用找到的第一個包含 main
方法的已編譯類別。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputDirectory
包含產生歸檔的目錄。
名稱 |
|
---|---|
類型 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputTimestamp
用於可重現輸出歸檔項目的時間戳記,格式為 ISO 8601 (yyyy-MM-dd'T'HH:mm:ssXXX
) 或表示自 epoch 以來秒數的 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
中,則無需在外掛程式組態中明確設定它。
如果設定了明確的版面配置,則始終會忽略版面配置工廠。
依賴排除
預設情況下,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
layers-xsd: https://www.springframework.org/schema/boot/layers/layers-3.3.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
圖層,其中包含所有 groupId
為 com.acme
的程式庫。