一、插件和目标 1、插件 Maven 的核心程序仅仅负责宏观调度,不做具体工作。具体工作都是由 Maven 插件完成的。例如:编译就是由 maven-compiler-plugin-3.1.jar 插件来执行的。
2、目标 一个插件可以对应多个目标,而每一个目标都和生命周期中的某一个环节对应。
Default 生命周期中有 compile 和 test-compile 两个和编译相关的环节,这两个环节对应 compile 和 test-compile 两个目标,而这两个目标都是由 maven-compiler-plugin-3.1.jar 插件来执行的。
3、调用插件的方法 方式一 :通过生命周期映射的方式,将插件的goal绑定到生命周期中的phase上,然后调用phase。例如:maven-jar-plugin插件提供了一个叫jar的goal,默认会绑定到生命周期的package阶段(phase)。调用mvn package 就会自动调用maven-jar-plugin:jar 。生命周期中所有前置的phase会先自动执行。
1
package <= => maven - jar - plugin : jar
方式二 :直接调用插件的某个功能(goal)。如mvn maven-jar-plugin:jar 。maven有一个约定,如果插件的名字叫maven-xxxx-plugin或xxxx-maven-plugin的话。可以直接用mvn xxxx:goal的方式调用其提供的功能。所以前面这个命令就可以简写成:mvn jar:jar 。这种方式只会执行指定的goal 。
调用goal完整的命令格式为:
1
2
mvn <plugin-prefix>:<goal>
mvn [<plugin-group-id>:]<plugin-artifact-id>[:<plugin-version>]:<goal>
可以通过命令查看插件的详细信息:
1
mvn help:describe -Dplugin= org.apache.maven.plugins:maven-compile-plugin –Ddetail
二、build标签 1、介绍 在实际使用 Maven 的过程中,我们会发现 build 标签有时候有,有时候没,这是怎么回事呢?其实通过有效 POM 我们能够看到,build 标签的相关配置其实一直都在,只是在我们需要定制构建过程的时候才会通过配置 build 标签覆盖默认值或补充配置。这一点我们可以通过打印有效 POM 来看到。
所以本质 上来说:我们配置的 build 标签都是对超级 POM 配置 的叠加 。那我们又为什么要在默认配置的基础上叠加呢?很简单,在默认配置无法满足需求的时候定制构建过程 。
2、build标签组成 ①、定义约定的目录结构 参考示例中的如下部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<sourceDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\src\main\java</sourceDirectory>
<scriptSourceDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\src\main\scripts</scriptSourceDirectory>
<testSourceDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\src\test\java</testSourceDirectory>
<outputDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\target\classes</outputDirectory>
<testOutputDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\target\test-classes</testOutputDirectory>
<resources>
<resource>
<directory> D:\idea2019workspace\atguigu-maven-test-prepare\src\main\resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory> D:\idea2019workspace\atguigu-maven-test-prepare\src\test\resources</directory>
</testResource>
</testResources>
<directory> D:\idea2019workspace\atguigu-maven-test-prepare\target</directory>
我们能看到各个目录的作用如下:
目录名 作用 sourceDirectory 主体源程序存放目录 scriptSourceDirectory 脚本源程序存放目录 testSourceDirectory 测试源程序存放目录 outputDirectory 主体源程序编译结果输出目录 testOutputDirectory 测试源程序编译结果输出目录 resources 主体资源文件存放目录 testResources 测试资源文件存放目录 directory 构建结果输出目录
②、备用插件管理 pluginManagement 标签存放着几个极少用到的插件:
maven-antrun-plugin maven-assembly-plugin maven-dependency-plugin maven-release-plugin 通过 pluginManagement 标签管理起来的插件就像 dependencyManagement 一样,子工程使用时可以省略版本号,起到在父工程中统一管理版本的效果。情看下面例子:
被 spring-boot-dependencies 管理的插件信息: 1
2
3
4
5
6
7
8
9
<pluginManagement>
<plugins>
<plugin>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-maven-plugin</artifactId>
<version> 2.6.2</version>
</plugin>
</plugins>
</pluginManagement>
1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
③、插件结构 plugins 标签存放的是默认生命周期中实际会用到的插件,这些插件想必大家都不陌生,所以抛开插件本身不谈,我们来看看 plugin 标签的结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<artifactId> maven-compiler-plugin</artifactId>
<version> 3.1</version>
<executions>
<execution>
<id> default-compile</id>
<phase> compile</phase>
<goals>
<goal> compile</goal>
</goals>
</execution>
<execution>
<id> default-testCompile</id>
<phase> test-compile</phase>
<goals>
<goal> testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
[1] 坐标部分 artifactId 和 version 标签定义了插件的坐标,作为 Maven 的自带插件这里省略了 groupId。 [2] 执行部分 executions 标签内可以配置多个 execution 标签,execution 标签内:
id:指定唯一标识 phase:关联的生命周期阶段 goals/goal:关联指定生命周期的目标goals 标签中可以配置多个 goal 标签,表示一个生命周期环节可以对应当前插件的多个目标。 另外,插件目标的执行过程可以进行配置,例如 maven-site-plugin 插件的 site 目标: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<execution>
<id> default-site</id>
<phase> site</phase>
<goals>
<goal> site</goal>
</goals>
<configuration>
<outputDirectory> D:\idea2019workspace\atguigu-maven-test-prepare\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</execution>
configuration 标签内进行配置时使用的标签是插件本身定义的。就以 maven-site-plugin 插件为例,它的核心类是 org.apache.maven.plugins.site.render.SiteMojo,在这个类中我们看到了 outputDirectory 属性:
SiteMojo 的父类是:AbstractSiteRenderingMojo,在父类中我们看到 reportPlugins 属性:
结论 :每个插件能够做哪些设置都是各个插件自己规定的,无法一概而论。三、定义jdk版本和编码 1、直接使用默认取值 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<properties>
<!-- maven-resources-plugin和maven-compiler-plugin插件的默认取值 -->
<project.build.sourceEncoding> UTF-8</project.build.sourceEncoding>
<!-- maven-site-plugin等插件的默认取值 -->
<project.reporting.outputEncoding> UTF-8</project.reporting.outputEncoding>
<!-- maven-compiler-plugin插件的默认取值 -->
<maven.compiler.source> 1.8</maven.compiler.source>
<maven.compiler.target> 1.8</maven.compiler.target>
<!-- spring-boot-starter-parent里定义的的默认取值 -->
<java.version> 1.8</java.version>
</properties>
2、或者在插件中定义 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<project>
[...]
<!-- build 标签:意思是告诉 Maven,你的构建行为,我要开始定制了! -->
<build>
[...]
<!-- plugins 标签:Maven 你给我听好了,你给我构建的时候要用到这些插件! -->
<plugins>
<!-- JDK版本 -->
<plugin>
<!-- 插件的坐标。此处引用的 maven-compiler-plugin 插件不是第三方的,是一个 Maven 自带的插件。 -->
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-compiler-plugin</artifactId>
<version> 3.10.1</version>
<!-- configuration 标签:配置 maven-compiler-plugin 插件 -->
<configuration>
<!-- 具体配置信息会因为插件不同、需求不同而有所差异 -->
<source> 1.8</source>
<target> 1.8</target>
<encoding> UTF-8</encoding>
</configuration>
</plugin>
<!-- 编码 -->
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-resources-plugin</artifactId>
<version> 3.2.0</version>
<configuration>
...
<encoding> UTF-8</encoding>
...
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
source 标签含义
翻译过来就是:调用 Java 编译器命令时传入的 -source 参数。那对编译器来说,-source 参数是啥意思呢?
『提供与指定发行版的源兼容性』这句话我的理解是:
我们写代码是按 JDK 1.8 写的——这就是『源兼容性』里的『源』。 指定发行版就是我们指定的 JDK 1.8。 『兼容性』是谁和谁兼容呢?现在源代码是既定的,所以就是要求编译器使用指定的 JDK 版本来兼容我们的源代码。 target 标签含义
调用 Java 编译器命令时传入的 -target 参数
『生成特定 VM 版本的类文件』这句话我的理解是:
VM 指 JVM 类文件指 *.class 字节码文件 整体意思就是源文件编译后,生成的 *.class 字节码文件要符合指定的 JVM 版本 3、或写在超级pom里,全局设定 配置的方式是:将 profile 标签整个复制到 settings.xml 文件的 profiles 标签内。
1
2
3
4
5
6
7
8
9
10
11
12
<profile>
<id> jdk-1.8</id>
<activation>
<activeByDefault> true</activeByDefault>
<jdk> 1.8</jdk>
</activation>
<properties>
<maven.compiler.source> 1.8</maven.compiler.source>
<maven.compiler.target> 1.8</maven.compiler.target>
<maven.compiler.compilerVersion> 1.8</maven.compiler.compilerVersion>
</properties>
</profile>
不推荐,仅在本地生效,如果脱离当前的settings.xml能够覆盖的范围,则无法生效
四、help 插件的各个目标 官网说明地址:https://maven.apache.org/plugins/maven-help-plugin
目标 说明 help:active-profiles 列出当前已激活的 profile help:all-profiles 列出当前工程所有可用 profile help:describe 描述一个插件和/或 Mojo 的属性 help:effective-pom 以 XML 格式展示有效 POM help:effective-settings 为当前工程以 XML 格式展示计算得到的 settings 配置 help:evaluate 计算用户在交互模式下给出的 Maven 表达式 help:system 显示平台详细信息列表,如系统属性和环境变量
五、springboot打包插件 1、打包 1
2
3
4
5
6
7
8
9
<build>
<plugins>
<plugin>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-maven-plugin</artifactId>
<version> 2.5.5</version>
</plugin>
</plugins>
</build>
很显然 spring-boot-maven-plugin 并不是 Maven 自带的插件,而是 SpringBoot 提供的,用来改变 Maven 默认的构建行为。具体来说是改变打包的行为。默认情况下 Maven 调用 maven-jar-plugin 插件的 jar 目标,生成普通的 jar 包。
普通 jar 包没法使用 java -jar xxx.jar 这样的命令来启动、运行,但是 SpringBoot 的设计理念就是每一个『微服务』导出为一个 jar 包,这个 jar 包可以使用 java -jar xxx.jar 这样的命令直接启动运行。
这样一来,打包的方式肯定要进行调整。所以 SpringBoot 提供了 spring-boot-maven-plugin 这个插件来定制打包行为。
2、插件的七个目标 目标名称 作用 spring-boot:build-image Package an application into a OCI image using a buildpack. spring-boot:build-info Generate a build-info.properties file based on the content of the current MavenProject. spring-boot:help Display help information on spring-boot-maven-plugin. Call mvn spring-boot:help -Ddetail=true -Dgoal= to display parameter details. spring-boot:repackage Repackage existing JAR and WAR archives so that they can be executed from the command line using java -jar. With layout=NONE can also be used simply to package a JAR with nested dependencies (and no main class, so not executable). spring-boot:run Run an application in place. spring-boot:start Start a spring application. Contrary to the run goal, this does not block and allows other goals to operate on the application. This goal is typically used in integration test scenario where the application is started before a test suite and stopped after. spring-boot:stop Stop an application that has been started by the ‘start’ goal. Typically invoked once a test suite has completed.
六、自定义插件 1、创建工程
**[2] AbstractMojo 抽象
我们实现 Mojo 接口比较困难,幸好可以继承 AbstractMojo,此时我们只要实现 execute() 这一个方法即可。
1
2
3
4
5
6
public class MyHelloPlugin extends AbstractMojo {
@Override
public void execute () throws MojoExecutionException , MojoFailureException {
getLog (). info ( "---> This is my first maven plugin. <---" );
}
}
2、插件配置 ①、Mojo 类中的配置 对应的 pom.xml 中的依赖: maven-plugin-api
对应 pom.xml 中的依赖:maven-plugin-annotations
1
2
3
4
5
6
7
8
// name 属性:指定目标名称
@Mojo ( name = "firstBlood" )
public class MyPluginOfFistBlood extends AbstractMojo {
@Override
public void execute () throws MojoExecutionException , MojoFailureException {
getLog (). info ( "---> first blood <---" );
}
}
②、安装插件 要在后续使用插件,就必须至少将插件安装到本地仓库。 mvn install
③、注册插件 我们需要将插件坐标中的 groupId 部分注册到 settings.xml 中。
1
2
3
4
5
6
7
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
<pluginGroup> com.atguigu.maven</pluginGroup>
</pluginGroups>
3、使用插件 ①、识别插件前缀 Maven 根据插件的 artifactId 来识别插件前缀。例如下面两种情况:
[1]前置匹配
匹配规则:${prefix}-maven-plugin artifactId:hello-maven-plugin 前缀:hello [2]中间匹配
匹配规则:maven-${prefix}-plugin artifactId:maven-good-plugin 前缀:good ②在命令行直接用 效果:
③、配置到 build 标签里用 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<build>
<plugins>
<plugin>
<groupId> com.atguigu.maven</groupId>
<artifactId> hello-maven-plugin</artifactId>
<version> 1.0-SNAPSHOT</version>
<executions>
<execution>
<id> hello</id>
<!-- 指定和目标关联的生命周期阶段 -->
<phase> clean</phase>
<goals>
<goal> sayHello</goal>
</goals>
</execution>
<execution>
<id> blood</id>
<phase> validate</phase>
<goals>
<goal> firstBlood</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行已和插件目标绑定的生命周期:
七、maven常用插件 1、maven-compiler-plugin 默认绑定到comile phase。用于编译项目源代码。
compile目标会编译src/main/java
目录下的源代码。
testCompile目标会编译src/test/java
目录下的测试代码。
maven compile
编译源代码。
maven testCompile
编译源代码+测试代码。
配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-compiler-plugin</artifactId>
<version> 3.6.0</version>
<configuration>
<source> 1.8</source> <!-- 源代码使用jdk1.8支持的特性 -->
<target> 1.8</target> <!-- 使用jvm1.8编译目标代码 -->
<encoding> utf-8</encoding> <!-- 编码 -->
<skipTests> true</skipTests> <!-- 是否跳过测试 -->
<showWarnings> true</showWarnings>
<meminitial> 128m</meminitial> <!-- 编译器使用的初始内存 -->
<maxmem> 512m</maxmem> <!-- 编译器使用的最大内存 -->
<compilerArgs> <!-- 传递参数 -->
<compilerArgs> <!-- 传递参数 -->
<arg> -Xlint:unchecked</arg> <!--启用对未经检查的转换的警告 Map map = new HashMap();
map.put("a", new A());-->
<arg> -Xlint:deprecation</arg> <!--显示关于使用了过时的 API 的详细信息-->
</compilerArgs>
</configuration>
</plugin>
用户可以通过两种方式调用Maven插件目标。
第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已,例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定,因此命令mvn compile 实际上是先定位到compile这一生命周期阶段,然后再根据绑定关系调用maven-compiler-plugin的compile目标。
第二种方式是直接在命令行指定要执行的插件目标,例如mvn archetype:generate 就表示调用maven-archetype-plugin的generate目标,这种带冒号的调用方式与生命周期无关。
2、maven-resources-plugin ①、分环境配置 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-resources-plugin</artifactId>
<version> 2.5</version>
<configuration>
<resources>
<resource>
<directory> src/main/resources</directory>
<!-- 先把所有环境的配置全部排除 -->
<excludes>
<exclude> dev/**</exclude>
<exclude> prod/**</exclude>
</excludes>
</resource>
<resource>
<directory> src/main/resources/${active.profile}</directory>
<!-- 再把当前环境的配置引入 -->
<includes>
<include> **/*.xml</include>
<include> **/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</plugin>
<!-- 或者 -->
<build>
<resources>
<resource>
<directory> src/main/resources</directory>
<!-- 先把所有环境的配置全部排除 -->
<excludes>
<exclude> dev/**</exclude>
<exclude> prod/**</exclude>
</excludes>
</resource>
<resource>
<directory> src/main/resources/${active.profile}</directory>
<!-- 再把当前环境的配置引入 -->
<includes>
<include> **/*.xml</include>
<include> **/*.properties</include>
</includes>
</resource>
</resources>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<profiles>
<profile>
<id> dev</id>
<activation>
<activeByDefault> true</activeByDefault>
</activation>
<properties>
<active.profile> dev</active.profile>
</properties>
</profile>
<profile>
<id> prod</id>
<properties>
<active.profile> prod</active.profile>
</properties>
</profile>
</profiles>
②、打源码包 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<build>
<plugins>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-source-plugin</artifactId>
<version> 3.0.1</version>
<executions>
<execution>
<id> attach-sources</id>
<phase> verify</phase>
<goals>
<goal> jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
3、maven-surefire-plugin 用于跑测试用例
此插件可以不在pom.xml里面声明,maven运行命令时,会自动调用该插件。
一些有用的配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore> true</testFailureIgnore> <!--测试有失败用例时,是否继续构建-->
<skipTests> true</skipTests> <!--是否跳过测试阶段,方式1-->
<skip> true</skip> <!--是否跳过测试阶段,方式2-->
<skipAfterFailureCount> 1</skipAfterFailureCount> <!-- 只要有一个用例测试失败,就立即停止。默认情况下会跑完所有测试用例 -->
<rerunFailingTestsCount> 2</rerunFailingTestsCount> <!-- 失败重试次数 -->
<parallel> methods</parallel> <!-- 并发执行测试用例 -->
<threadCount> 10</threadCount> <!-- 并发执行时的线程数量 -->
</configuration>
</plugin>
4、spring-boot-maven-plugin spring-boot开发必备插件。它能将spring-boot项目代码及其依赖jar打包成一个完整的可执行的jar包(fat jar)作用和插件maven-shade-plugin
差不多。
repackage的goal绑定在生命周期的package阶段。
使用方式:
1
2
3
4
5
6
7
8
9
10
11
<plugin>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal> repackage</goal>
</goals>
</execution>
</executions>
</plugin>
如果指定了spring-boot作为parent,可以不指定版本和repackage goal
:
1
2
3
4
5
6
7
8
9
10
11
12
13
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-starter-parent</artifactId>
<version> 1.3.8.RELEASE</version>
<configuration>
<mainClass> ${start-class}</mainClass>
</configuration>
</parent>
<plugin>
<groupId> org.springframework.boot</groupId>
<artifactId> spring-boot-maven-plugin</artifactId>
</plugin>
spring-boot查找main文件的流程是:
1、首先查看<mainClass>
是否有值,如果有,直接拿标签内的类名作为入口。
1
2
3
<properties>
<start-class> com.example.Application</start-class>
</properties>
2、如果没找到<start-class>
标签,会遍历所有文件,找到注解了@SpringBootApplication
并含有main方法的类,将其作为入口。
实践证明,如果没有定义<start-class>
,查找入口类的方法也是非常快的。
在实际开发中,推荐手动定义<start-class>
。这样在一个项目工程中可以有多个@SpringBootApplication
注解的类,修改一下pom里的配置就能灵活切换入口了。
5、maven-jar-plugin 这个是普通java项目(非java web项目和其他特殊类型的java项目)package阶段默认绑定的插件,能够将编译好的class和资源打成jar包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-jar-plugin</artifactId>
<version> 3.0.2</version>
<configuration>
<archive>
<!--加描述-->
<addMavenDescriptor> false</addMavenDescriptor>
<manifest>
<!--是否要把第三方jar放到manifest的classpath中-->
<addClasspath> true</addClasspath>
<!--生成的manifest中classpath的前缀,因为要把第三方jar放到lib目录下,不是代码里的目录-->
<classpathPrefix> lib/</classpathPrefix>
<!-- 执行的主程序路径 -->
<mainClass> com.meix.boot.Application</mainClass>
</manifest>
</archive>
<!-- 过滤掉不希望包含在jar中的文件 -->
<excludes>
<exclude> *.xml</exclude>
<exclude> spring/**</exclude>
<exclude> config/**</exclude>
</excludes>
<!-- 把配置的这个目录下的部分资源打包,其他目录的java类不打 -->
<includes>
<include> **/api/*</include>
</includes>
</configuration>
</plugin>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-dependency-plugin</artifactId>
<version> 2.10</version>
<executions>
<execution>
<id> copy-dependencies</id>
<phase> package</phase>
<goals>
<goal> copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory> ${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
打开 MENIFEST.MF 文件可以看到如下内容:
1
2
3
4
5
6
7
8
9
10
11
Manifest-Version : 1.0
Archiver-Version : Plexus Archiver
Built-By : sandy
//表示依赖的第三方jar包在哪里,显然需要放在和 当前jar包同级目录下的 lib文件夹下
Class-Path : lib/gson-2.8.5.jar lib/guava-19.0.jar lib/slf4j-api-1.7.25
.jar lib/logback-core-1.2.3.jar lib/logback-access-1.2.3.jar lib/logb
ack-classic-1.2.3.jar lib/lombok-1.18.2.jar lib/commons-lang3-3.8.1.j
ar lib/commons-io-2.2.jar
Created-By : Apache Maven 3.5.2
Build-Jdk : 1.8.0_121
Main-Class : com.example.demo.test.App //表示运行的主程序
所以安装包的路径结构应该是:
为此需要 通过 maven-assembly-plugin 插件来组装出安装包。
针对本示例 对应的 maven-assembly-plugin 配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-assembly-plugin</artifactId>
<executions>
<execution>
<id> make-assembly</id>
<phase> package</phase>
<goals>
<goal> single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<!-- 和 pom.xml 同级目录下 -->
<descriptor> assembly.xml</descriptor>
</descriptors>
<!-- assembly 组装出来的包会被放置在和 pom.xml同级目录下的output目录下 -->
<outputDirectory> output</outputDirectory>
<!-- true:会在生成的zip包名后面加上 id-->
<appendAssemblyId> false</appendAssemblyId>
</configuration>
</plugin>
assembly.xml 内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version='1.0' encoding='UTF-8'?>
<assembly xmlns= "http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd" >
<id> test-maven</id>
<formats>
<format> zip</format>
</formats>
<includeBaseDirectory> false</includeBaseDirectory>
<fileSets>
<fileSet>
<!-- ${project.build.directory} 指 target目录 -->
<directory> ${project.build.directory}</directory>
<!-- 表示输出到 pom 中配置的 output目录下 -->
<outputDirectory> /</outputDirectory>
<includes>
<!-- 把jar放入zip包根目录 -->
<include> test-maven*.jar</include>
<!-- dependency插件复制的依赖jar放入zip -->
<include> lib/*</include>
</includes>
</fileSet>
<fileSet>
<directory> ${project.build.directory}/classes</directory>
<!-- 表示输出到 pom 中配置的 output/config 目录下 -->
<outputDirectory> /config</outputDirectory>
<includes>
<include> application.properties</include>
</includes>
</fileSet>
<fileSet>
<!-- ${project.basedir} 指 工程根目录 -->
<directory> ${project.basedir}</directory>
<outputDirectory> /</outputDirectory>
<includes>
<include> doc/*.*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
要自定义 jar 包名称,可以直接在 pom.xml 中 build 结点下设置 finalName,如:
1
2
3
<build>
<finalName> p-test-tool</finalName>
</build>
6、maven-assembly-plugin 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<build>
<plugins>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-assembly-plugin</artifactId>
<executions>
<execution>
<id> make-assembly</id>
<phase> package</phase>
<goals>
<goal> single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<!-- 使用官方的打包策略 -->
<descriptorRef> jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass> a.App</mainClass>
</manifest>
</archive>
<!-- assembly 组装出来的包会被放置在和 pom.xml同级目录下的output目录下 -->
<outputDirectory> output</outputDirectory>
<!-- true:会在生成的zip包名后面加上 id-->
<appendAssemblyId> false</appendAssemblyId>
</configuration>
</plugin>
</plugins>
</build>
7、maven-shade-plugin 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<build>
<plugins>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-shade-plugin</artifactId>
<version> 3.3.0</version>
<executions>
<execution>
<phase> package</phase>
<goals>
<goal> shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation= "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" >
<mainClass> org.sonatype.haven.HavenCli</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>