我們先明確下Packaging的含義(部分內容轉載自:Maven實戰(九)——打包的技巧)
任何一個Maven項目都需要定義POM元素packaging(如果不寫則默認值為jar)。顧名思義,該元素決定了項目的打包方式。實際的情形中,如果你不聲明該元素,Maven會幫你生成一個JAR包;如果你定義該元素的值為war,那你會得到一個WAR包;如果定義其值為POM(比如是一個父模塊),那什么包都不會生成。
下面我們來看看maven自帶的幾種打包工具:
maven-jar-plugin
(我們可以通過mvn help:describe
命令來查看插件、命令等操作的詳細說明,比如我們在命令行執行mvn help:describe -Dplugin=org.apache.maven.plugins:maven-jar-plugin
,便可以看到maven-jar-plugin插件的詳細介紹)
jar項目默認的打包工具,默認情況下只會將項目源碼編譯生成的class文件和資源文件打包進來,不會打包進項目依賴的jar包。
maven-war-plugin
war項目默認的打包工具,默認情況下會打包項目編譯生成的.class文件、資源文件以及項目依賴的所有jar包。
maven-assembly-plugin
需要在pom文件的plugin元素中引入才可以使用,功能非常強大,是maven中針對打包任務而提供的標準插件。它是Maven最強大的打包插件,它支持各種打包文件格式,包括zip、tar.gz、tar.bz2等等,通過一個打包描述文件設置(src/main/assembly.xml),它能夠幫助用戶選擇具體打包哪些資源文件集合、依賴、模塊,甚至本地倉庫文件,每個項的具體打包路徑用戶也能自由控制。
maven-shade-plugin
需要在pom文件的plugin元素中引入才可以使用,它可以讓用戶配置Main-Class的值,然后在打包的時候將值填入/META-INF/MANIFEST.MF文件。關于項目的依賴,它很聰明地將依賴的JAR文件全部解壓后,再將得到的.class文件連同當前項目的.class文件一起合并到最終的CLI包(可以直接運行的jar包)中,這樣,在執行CLI JAR文件的時候,所有需要的類就都在Classpath中了。
如何選用這幾個插件
- 如果在開發一個庫,直接使用默認的maven-jar-plugin插件即可;
- 如果是開發一個應用程序,可以考慮使用maven-shade-plugin進行打包生成über jar(über jar是將應用程序打包到單獨的jar包中,該jar包包含了應用程序依賴的所有庫和二進制包)
- 如果打包生成了über jar都不能滿足你的需求的話,那么推薦使用maven-assembly-plugin插件來自定義打包內容。
我們再來看看SpringBoot的spring-boot-maven-plugin插件的打包功能
spring-boot-maven-plugin
spring-boot-maven-plugin插件在Maven中提供了對Spring Boot的支持,可以幫助我們打包出可執行的jar包或者war包。其實spring-boot-maven-plugin所做的工作是在默認的maven-jar-plugin插件打包結束后,將項目依賴的jar包中的.class文件重新進行打包。
[INFO]
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ helloworld ---
[INFO] Building jar: /Users/gaozengrong/IdeaProjects/helloworld/target/helloworld-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) @ helloworld ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 26.357 s
[INFO] Finished at: 2017-03-19T17:51:33+08:00
[INFO] Final Memory: 33M/289M
[INFO] ------------------------------------------------------------------------
可以看出,在調用maven-jar-plugin的goal:jar任務打包之后,又調用了spring-boot-maven-plugin的goal:repackage任務,這樣會產生兩個jar包。在helloworld這個工程里分別對應helloworld-1.0-SNAPSHOT.jar.original
(maven-jar-plugin打包生成的jar包),helloworld-1.0-SNAPSHOT.jar
(spring-boot-maven-plugin重新打包生成的可執行jar包)。