我们先明确下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包)。