封裝可執行歸檔

此外掛程式可以建立包含應用程式所有依賴的可執行歸檔(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 階段建置的 jarwar 歸檔,包括專案中定義的任何 provided 依賴。如果需要排除其中一些依賴,您可以使用其中一個 exclude 選項;請參閱依賴排除以取得更多詳細資訊。

原始(即非可執行)工件預設會重新命名為 .original,但也可以使用自訂分類器來保留原始工件。

目前不支援 maven-war-pluginoutputFileNameMapping 功能。

spring-boot-devtoolsspring-boot-docker-compose 模組預設會自動排除(您可以使用 excludeDevtoolsexcludeDockerCompose 屬性來控制此行為)。為了使其與 war 封裝搭配使用,spring-boot-devtoolsspring-boot-docker-compose 依賴必須設定為 optional 或具有 provided 範圍。

此外掛程式會重寫您的 manifest,尤其是它會管理 Main-ClassStart-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 屬性預設為由歸檔類型(jarwar)決定的值。以下版面配置可用

  • JAR:一般可執行 JAR 版面配置。

  • WAR:可執行 WAR 版面配置。provided 依賴會放置在 WEB-INF/lib-provided 中,以避免當 war 部署在 servlet 容器中時發生任何衝突。

  • ZIPDIR 的別名):類似於使用 PropertiesLauncherJAR 版面配置。

  • NONE:捆綁所有依賴和專案資源。不捆綁啟動載入器。

分層 Jar 或 War

重新封裝的 jar 在 BOOT-INF/classesBOOT-INF/lib 中分別包含應用程式的類別和依賴。同樣地,可執行 war 在 WEB-INF/classes 中包含應用程式的類別,在 WEB-INF/libWEB-INF/lib-provided 中包含依賴。對於需要從 jar 或 war 的內容建置 docker 映像檔的情況,能夠進一步分隔這些目錄會很有用,以便它們可以寫入不同的層。

分層歸檔使用與一般重新封裝 jar 或 war 相同的版面配置,但包含描述每個層的其他元資料檔案。

預設情況下,定義了以下層

  • dependencies 用於任何版本不包含 SNAPSHOT 的依賴。

  • spring-boot-loader 用於載入器類別。

  • snapshot-dependencies 用於任何版本包含 SNAPSHOT 的依賴。

  • application 用於本機模組依賴、應用程式類別和資源。

模組依賴是透過查看目前建置中包含的所有模組來識別的。如果模組依賴只能因為它已安裝到 Maven 的本機快取中,並且不屬於目前的建置而解析,則它將被識別為一般依賴。

層的順序很重要,因為它決定了當應用程式的一部分變更時,先前層可以快取的可能性。預設順序為 dependenciesspring-boot-loadersnapshot-dependenciesapplication。最不可能變更的內容應先新增,然後再新增更可能變更的層。

重新封裝的歸檔預設包含 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。

必要參數

名稱 類型 預設值

outputDirectory

檔案

${project.build.directory}

選用參數

名稱 類型 預設值

attach

布林值

true

classifier

字串

embeddedLaunchScript

檔案

embeddedLaunchScriptProperties

屬性

excludeDevtools

布林值

true

excludeDockerCompose

布林值

true

excludeGroupIds

字串

excludes

清單

executable

布林值

false

includeSystemScope

布林值

false

includeTools

布林值

true

includes

清單

layers

Layers

layout

LayoutType

layoutFactory

LayoutFactory

loaderImplementation

LoaderImplementation

mainClass

字串

outputTimestamp

字串

${project.build.outputTimestamp}

requiresUnpack

清單

skip

布林值

false

參數詳細資訊

attach

附加重新封裝的歸檔,以便安裝到您的本機 Maven 儲存庫或部署到遠端儲存庫。如果未設定分類器,它將取代正常的 jar。如果已設定 classifier,使得正常的 jar 和重新封裝的 jar 不同,則它將與正常的 jar 一起附加。當屬性設定為 false 時,將不會安裝或部署重新封裝的歸檔。

名稱

attach

類型

布林值

預設值

true

使用者屬性

1.4.0

classifier

要新增到重新封裝歸檔的分類器。如果未給定,則主要工件將被重新封裝的歸檔取代。如果給定,分類器也將用於決定要重新封裝的來源歸檔:如果具有該分類器的工件已存在,則它將用作來源並被取代。如果不存在此類工件,則主要工件將用作來源,並且重新封裝的歸檔將作為具有該分類器的補充工件附加。附加工件允許將其與原始工件一起部署,請參閱Maven 文件以取得更多詳細資訊

名稱

classifier

類型

java.lang.String

預設值

使用者屬性

1.0.0

embeddedLaunchScript

如果 jar 是完全可執行的,則要前置於 jar 前面的嵌入式啟動腳本。如果未指定,將使用「Spring Boot」預設腳本。

名稱

embeddedLaunchScript

類型

java.io.File

預設值

使用者屬性

1.3.0

embeddedLaunchScriptProperties

應在嵌入式啟動腳本中展開的屬性。

名稱

embeddedLaunchScriptProperties

類型

java.util.Properties

預設值

使用者屬性

1.3.0

excludeDevtools

從重新封裝的歸檔中排除 Spring Boot 開發工具。

名稱

excludeDevtools

類型

布林值

預設值

true

使用者屬性

spring-boot.repackage.excludeDevtools

1.3.0

excludeDockerCompose

從重新封裝的歸檔中排除 Spring Boot 開發服務。

名稱

excludeDockerCompose

類型

布林值

預設值

true

使用者屬性

spring-boot.repackage.excludeDockerCompose

3.1.0

excludeGroupIds

要排除的 groupId 名稱的逗號分隔清單(完全比對)。

名稱

excludeGroupIds

類型

java.lang.String

預設值

使用者屬性

spring-boot.excludeGroupIds

1.1.0

excludes

要排除的工件定義集合。Exclude 元素定義了強制性的 groupIdartifactId 組件以及選用的 classifier 組件。當設定為屬性時,值應以逗號分隔,組件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier

名稱

excludes

類型

java.util.List

預設值

使用者屬性

spring-boot.excludes

1.1.0

executable

透過在 jar 前面加上啟動腳本,為 *nix 機器建立完全可執行的 jar。<p> 目前,某些工具不接受此格式,因此您可能不一定能夠使用此技術。例如,jar -xf 可能會靜默地無法解壓縮已設為完全可執行的 jar 或 war。建議您僅在打算直接執行它,而不是使用 java -jar 執行它或將其部署到 servlet 容器時,才啟用此選項。

名稱

executable

類型

布林值

預設值

false

使用者屬性

1.3.0

includeSystemScope

包含系統範圍的依賴。

名稱

includeSystemScope

類型

布林值

預設值

false

使用者屬性

1.4.0

includeTools

包含 JAR 工具。

名稱

includeTools

類型

布林值

預設值

true

使用者屬性

3.3.0

includes

要包含的工件定義集合。Include 元素定義了強制性的 groupIdartifactId 組件以及選用的 classifier 組件。當設定為屬性時,值應以逗號分隔,組件以冒號分隔:groupId:artifactId,groupId:artifactId:classifier

名稱

includes

類型

java.util.List

預設值

使用者屬性

spring-boot.includes

1.2.0

layers

層組態,具有停用層建立、排除層工具 jar 以及提供自訂層組態檔案的選項。

名稱

layers

類型

org.springframework.boot.maven.Layers

預設值

使用者屬性

2.3.0

layout

歸檔的類型(對應於依賴在其中配置的方式)。可能的值為 JARWARZIPDIRNONE。預設為根據歸檔類型猜測。

名稱

layout

類型

org.springframework.boot.maven.AbstractPackagerMojo$LayoutType

預設值

使用者屬性

spring-boot.repackage.layout

1.0.0

layoutFactory

如果未設定明確的版面配置,則將用於建立可執行歸檔的版面配置工廠。替代版面配置實作可以由第三方提供。

名稱

layoutFactory

類型

org.springframework.boot.loader.tools.LayoutFactory

預設值

使用者屬性

1.5.0

loaderImplementation

應使用的載入器實作。

名稱

loaderImplementation

類型

org.springframework.boot.loader.tools.LoaderImplementation

預設值

使用者屬性

3.2.0

mainClass

主類別的名稱。如果未指定,將使用找到的第一個包含 main 方法的已編譯類別。

名稱

mainClass

類型

java.lang.String

預設值

使用者屬性

1.0.0

outputDirectory

包含產生歸檔的目錄。

名稱

outputDirectory

類型

java.io.File

預設值

${project.build.directory}

使用者屬性

1.0.0

outputTimestamp

用於可重現輸出歸檔項目的時間戳記,格式為 ISO 8601 (yyyy-MM-dd'T'HH:mm:ssXXX) 或表示自 epoch 以來秒數的 int

名稱

outputTimestamp

類型

java.lang.String

預設值

${project.build.outputTimestamp}

使用者屬性

2.3.0

requiresUnpack

為了執行而必須從 uber jar 中解壓縮的程式庫清單。將每個程式庫指定為具有 <groupId><artifactId><dependency>,它們將在執行階段解壓縮。

名稱

requiresUnpack

類型

java.util.List

預設值

使用者屬性

1.1.0

skip

略過執行。

名稱

skip

類型

布林值

預設值

false

使用者屬性

spring-boot.repackage.skip

1.2.0

範例

自訂分類器

預設情況下,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-pluginspring-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 中,則無需在外掛程式組態中明確設定它。

如果設定了明確的版面配置,則始終會忽略版面配置工廠。

依賴排除

預設情況下,repackagerun 目標都會包含專案中定義的任何 provided 依賴項。Spring Boot 專案應將 provided 依賴項視為執行應用程式所需的「容器」依賴項。一般來說,Spring Boot 專案不會作為依賴項使用,因此不太可能有任何 optional 依賴項。當專案確實有可選依賴項時,repackagerun 目標也會包含它們。

其中一些依賴項可能完全不需要,應該從可執行 JAR 檔案中排除。為了保持一致性,在執行應用程式時也不應該存在這些依賴項。

有兩種方法可以從封裝/執行時使用的依賴項中排除依賴項

  • 排除由 groupIdartifactId 識別的特定構件,如果需要,還可以選擇使用 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 圖層,其中包含所有 groupIdcom.acme 的程式庫。