Maven ¶
Maven基础 ¶
- Maven可以管理jar文件
- 自动下载jar和他的文档,源代码
- 管理jar的直接依赖
- 管理所需要的jar文件版本
- 测试代码是否正确
- 打包文件,形成jar文件,或war文件
- 部署项目
构建:项目的构建
- 清理,把之前项目编译的东西删除掉
- 编译,把程序源代码编译成可执行代码,批量的
- 测试,Maven执行多个测试代码,验证程序是否正确,批量的
- 报告,生成测试结果文件,测试是否通过
- 打包,将项目所有文件资源打包到一个压缩文件中;对于通常的java程序,文件扩展名为jar;对于web应用,文件扩展名为war
- 安装,把步骤五打包的文件jar或war安装到本地仓库
- 部署
Maven核心概念
- POM:一个文件,名称是 pom.xml ,pom翻译过来就是项目对象模型;控制Maven构建项目过程,管理jar依赖
- 约定目录结构:Maven项目目录结构是规定的
- 坐标:唯一字符串,用于表示资源的
- 依赖管理:管理项目 jar 文件
- 仓库管理
- 生命周期
- 插件和目标
- 继承
- 聚合
Maven安装与配置
- 从 apache 官网下载 Maven 安装包
- 配置国内仓库,提升 Maven 速度
- 环境变量配置
- mvn -v 验证是否配置成功
Maven 核心 ¶
Maven 约定的目录结构
一个使用Maven管理的普通的Java项目,它的目录结构默认如下:
1a-Maven-project
2├── pom.xml #Maven的核心文件
3├── src
4│ ├── main #主程序
5│ │ ├── java
6│ │ └── resources #java中使用的配置文件
7│ └── test #测试代码
8│ ├── java
9│ └── resources
10└── target #编译生成的class项目对象模型 POM
项目描述文件pom.xml是Maven的灵魂,它的内容长得像下面:
1<project ...>
2 <modelVersion>4.0.0</modelVersion>
3 <groupId>com.itranswarp.learnjava</groupId>
4 <artifactId>hello</artifactId>
5 <version>1.0</version>
6 <packaging>jar</packaging>
7 <properties>
8 ...
9 </properties>
10 <dependencies>
11 <dependency>
12 <groupId>commons-logging</groupId>
13 <artifactId>commons-logging</artifactId>
14 <version>1.2</version>
15 </dependency>
16 </dependencies>
17</project>其中,groupId类似于Java的包名,通常是公司或组织名称,artifactId类似于Java的类名,通常是项目名称,再加上version,一个Maven工程就是由groupId,artifactId和version作为唯一标识。我们在引用其他第三方库的时候,也是通过这3个变量确定。例如,依赖commons-logging:
1<dependency>
2 <groupId>commons-logging</groupId>
3 <artifactId>commons-logging</artifactId>
4 <version>1.2</version>
5</dependency>使用<dependency>声明一个依赖后,Maven就会自动下载这个依赖包并把它放到classpath中。
以下为 pom 文件中常用的标签:
| 标签 | 说明 |
|---|---|
| groupId、artifactId、version | 唯一标志一个jar包 |
| packaging | 打包压缩文件后的扩展名,默认为jar |
| dependencies、dependency | 依赖,说明项目需要使用的 jar |
| properties | 定义属性,例如定义编码方式 |
| build | 与构建相关的属性,如指定 Maven 编译时的 jdk版本 |
坐标
对于某个依赖,Maven只需要3个变量即可唯一确定某个jar包:
- groupId:属于组织的名称,类似Java的包名;
- artifactId:该jar包自身的名称,类似Java的类名;
- version:该jar包的版本,后面带
-SNAPSHOT代表项目在开发阶段
仓库
- 仓库存放Maven使用的jar(也叫做插件)和我们项目使用的 jar
- 仓库分两种:本地仓库 和 远程仓库(中央仓库,中央仓库镜像,私服)
- 本地仓库—->私服—->镜像—->中央仓库
小结
- Maven使用 pom.xml 定义项目内容,并使用预定义目录结构
- 在 pom.xml 可以声明依赖,Maven会自动下载,并放入 classpath
- Maven使用 groupId,artifactId 和 version 唯一定位一个依赖
依赖管理 ¶
依赖关系
Maven定义了几种依赖关系,分别是compile、test、runtime和provided
| scope | 说明 | 示例 |
|---|---|---|
| compile | 编译时需要用到该jar包(默认) | commons-logging |
| test | 编译Test时需要用到该jar包 | junit |
| runtime | 编译时不需要,但运行时需要用到 | mysql |
| provided | 编译时需要用到,但运行时由JDK或某个服务器提供 | servlet-api |
test依赖表示仅在测试时使用,正常运行时并不需要。最常用的test依赖就是JUnit:
1<dependency>
2 <groupId>org.junit.jupiter</groupId>
3 <artifactId>junit-jupiter-api</artifactId>
4 <version>5.3.2</version>
5 <scope>test</scope>
6</dependency>搜索第三方组件
如果要引用一个第三方组件,比如okhttp,如何确切地获得它的groupId、artifactId和version?方法是通过search.Maven.org搜索关键字,找到对应的组件后,直接复制
小结
- Maven通过解析依赖关系确定项目所需的jar包,常用的4种
scope有:compile(默认),test,runtime和provided - Maven从中央仓库下载所需的jar包并缓存在本地
- 可以通过镜像仓库加速下载
构建流程(生命周期) ¶
构建流程
Maven 不但有标准化的项目结构,而且还有一套标准化的构建流程,可以自动化实现编译、打包、发布等等
Lifecycle 和 Phase
Maven的生命周期由一系列阶段(phase)构成
使用mvn这个命令时,后面的参数是phase,Maven自动根据生命周期运行到指定的phase
实际开发过程中,经常使用的命令有:
mvn clean:清理所有生成的class和jarmvn clean compile:先清理,再执行到compilemvn clean test:先清理,再执行到test,因为执行test前必须执行compile,所以这里不必指定compilemvn clean package:先清理,再执行到package
大多数phase在执行过程中,因为我们通常没有在pom.xml中配置相关的设置,所以这些phase什么事情都不做
经常用到的phase其实只有几个:
- clean:清理
- compile:编译
- test:运行测试
- package:打包
Goal
执行一个phase又会触发一个或多个goal:
| 执行的Phase | 对应执行的Goal |
|---|---|
| compile | compiler:compile |
| test | compiler:testCompile surefire:test |
goal的命名总是abc:xyz这种形式
类比一下:
- lifecycle相当于Java的package,它包含一个或多个phase;
- phase相当于Java的class,它包含一个或多个goal;
- goal相当于class的method,它其实才是真正干活的
小结
Maven通过lifecycle、phase和goal来提供标准的构建流程。
最常用的构建命令是指定phase,然后让Maven执行到指定的phase:
- mvn clean
- mvn clean compile
- mvn clean test
- mvn clean package
通常情况,我们总是执行phase默认绑定的goal,因此不必指定goal。
插件使用 ¶
Maven的 lifecycle,phase和goal:使用 Maven构建项目就是执行 lifecycle,执行到指定的push为止,每个push会执行自己默认的一个或多个 goal。goal是最小任务单元。
例如执行以下命令
1mvn compileMaven 将执行 compile 这个 phase,这个 phase 会调用 compiler 插件执行关联的 compiler:compile 这个goal
实际上,执行每个phase,都是通过某个插件(plugin)来执行的,Maven本身其实并不知道如何执行compile,它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译。
分析
所以,使用Maven,实际上就是配置好需要使用的插件,然后通过phase调用它们。
Maven已经内置了一些常用的标准插件:
| 插件名称 | 对应执行的phase |
|---|---|
| clean | clean |
| compiler | compile |
| surefire | test |
| jar | package |
如果标准插件无法满足需求,我们还可以使用自定义插件。使用自定义插件的时候,需要声明。例如,使用Maven-shade-plugin可以创建一个可执行的jar,要使用这个插件,需要在pom.xml中声明它:
1<project>
2 ...
3 <build>
4 <plugins>
5 <plugin>
6 <groupId>org.apache.Maven.plugins</groupId>
7 <artifactId>Maven-shade-plugin</artifactId>
8 <version>3.2.1</version>
9 <executions>
10 <execution>
11 <phase>package</phase>
12 <goals>
13 <goal>shade</goal>
14 </goals>
15 <configuration>
16 ...
17 </configuration>
18 </execution>
19 </executions>
20 </plugin>
21 </plugins>
22 </build>
23</project>自定义插件往往需要一些配置,例如,Maven-shade-plugin需要指定Java程序的入口,它的配置是:
1<configuration>
2 <transformers>
3 <transformer implementation="org.apache.Maven.plugins.shade.resource.ManifestResourceTransformer">
4 <mainClass>com.itranswarp.learnjava.Main</mainClass>
5 </transformer>
6 </transformers>
7</configuration>注意,Maven自带的标准插件例如compiler是无需声明的,只有引入其它的插件才需要声明。
下面列举了一些常用的插件:
- Maven-shade-plugin:打包所有依赖包并生成可执行jar;
- cobertura-Maven-plugin:生成单元测试覆盖率报告;
- findbugs-Maven-plugin:对Java源码进行静态分析以找出潜在问题。
小结
Maven通过自定义插件可以执行项目构建时需要的额外功能,使用自定义插件必须在pom.xml中声明插件及配置;
插件会在某个phase被执行时执行;
插件的配置和用法需参考插件的官方文档。
IDEA配置Maven ¶
- 配置当前工程
- 配置新建工程
都需要配置 Maven、配置文件、仓库
注意在VM Options中配置: -DarchetypeCatalog=internal 可以提升创建Maven项目的速度
单元测试 ¶
用 junit ,一个专门测试的框架(工具);测试的基本单元是方法
在 pom.xml 中加入依赖项
xml1 <dependency> 2 <groupId>junit</groupId> 3 <artifactId>junit</artifactId> 4 <version>4.12</version> 5 <scope>test</scope> 6 </dependency>在 Maven 项目下的 src/test/java 目录下,创建测试程序
- 测试类的名称 是 Test + 需要测试的类名
- 测试方法的名称是 Test + 方法名
java1//例如测试 Hello 中 add方法 2/* 3* 方法必须是public的 4* 方法必须没有返回值 5* 方法名称可以自定义 6* 方法上面添加注解 @Test 7*/ 8class TestHello 9 @Test 10 public void testAdd(){ 11 Hello hello=new Hello(); 12 int res=hello.add(10,20); 13 //该方法是 junit 提供的 14 // asserEquals(期望值,实际值),如果不等则抛出异常 15 Assert.assertEquals(30,res); 16 } 17}
多模块管理 ¶
意义
可以对子模块版本进行统一
Maven多模块管理,其实就是让它的子模块的pom文件继承父工程的pom文件
Maven父工程遵循以下要求
- packaging标签的文本内容必须设置为pom
- 把src目录删除掉
- 只是简单额留下一个pom.xml文件
父工程pom文件
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://Maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://Maven.apache.org/POM/4.0.0 http://Maven.apache.org/xsd/Maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>org.lei</groupId>
8 <artifactId>springboot</artifactId>
9 <version>1.0-SNAPSHOT</version>
10 <modules>
11 <!-- 子模块 -->
12 </modules>
13 <!-- 声明为pom -->
14 <packaging>pom</packaging>
15
16 <properties>
17 <!-- 定义变量 -->
18 <Maven.compiler.source>11</Maven.compiler.source>
19 <Maven.compiler.target>11</Maven.compiler.target>
20 <spring-boot.version>2.7.5</spring-boot.version>
21 <hutool.version>5.8.9</hutool.version>
22 </properties>
23
24 <!-- 子模块通用的的依赖,子模块无需单独导入,版本号在dependencyManagement中声明过 -->
25 <dependencies>
26 <dependency>
27 <groupId>cn.hutool</groupId>
28 <artifactId>hutool-all</artifactId>
29 </dependency>
30 <dependency>
31 <groupId>org.projectlombok</groupId>
32 <artifactId>lombok</artifactId>
33 </dependency>
34 </dependencies>
35
36 <!-- 依赖管理,子模块需要某个依赖时直接声明坐标,无需版本号 -->
37 <dependencyManagement>
38 <dependencies>
39 <!-- 导入springboot 依赖管理,其中定义了常用依赖版本 -->
40 <dependency>
41 <groupId>org.springframework.boot</groupId>
42 <artifactId>spring-boot-dependencies</artifactId>
43 <version>${spring-boot.version}</version>
44 <type>pom</type>
45 <scope>import</scope>
46 </dependency>
47 <dependency>
48 <groupId>cn.hutool</groupId>
49 <artifactId>hutool-all</artifactId>
50 <version>${hutool.version}</version>
51 </dependency>
52 </dependencies>
53 </dependencyManagement>
54
55</project>子模块pom文件
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://Maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://Maven.apache.org/POM/4.0.0 http://Maven.apache.org/xsd/Maven-4.0.0.xsd">
5
6 <!-- 声明父工程 -->
7 <parent>
8 <artifactId>springboot</artifactId>
9 <groupId>org.lei</groupId>
10 <version>1.0-SNAPSHOT</version>
11 </parent>
12
13 <modelVersion>4.0.0</modelVersion>
14
15 <!-- 模块名 -->
16 <artifactId>springdemo</artifactId>
17
18 <!-- 依赖,不需要声明版本,版本由父工程管理 -->
19 <dependencies>
20 <dependency>
21 <groupId>org.springframework.boot</groupId>
22 <artifactId>spring-boot-starter-web</artifactId>
23 </dependency>
24 <dependency>
25 <groupId>org.springframework</groupId>
26 <artifactId>spring-aspects</artifactId>
27 </dependency>
28 </dependencies>
29
30</project>pom 文件 ¶
1<?xml version="1.0" encoding="UTF-8"?>
2
3<project xmlns="http://Maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://Maven.apache.org/POM/4.0.0 http://Maven.apache.org/xsd/Maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7<!-- 通过 groupId、artifactId、version 唯一确定该项目-->
8 <groupId>org.lei</groupId>
9 <artifactId>ch02-Maven-web</artifactId>
10<!-- 版本后面加 -SNAPSHOT代表还在开发阶段-->
11 <version>1.0-SNAPSHOT</version>
12
13<!-- 打包成归档文件的类型 se项目jar、web项目war-->
14 <packaging>war</packaging>
15
16<!-- Maven属性配置-->
17 <properties>
18<!-- 编码格式-->
19 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20<!-- 编译使用 jdk 版本-->
21 <Maven.compiler.source>1.8</Maven.compiler.source>
22<!-- 运行使用 jdk版本-->
23 <Maven.compiler.target>1.8</Maven.compiler.target>
24<!-- 自定义属性变量,标签就是变量名,可以通过 ${变量名} 来使用-->
25 <juint-version>4.11</juint-version>
26 </properties>
27
28<!-- 依赖管理-->
29 <dependencies>
30<!-- 通过 groupId、artifactId、version 唯一确定一个jar-->
31 <dependency>
32 <groupId>javax.servlet</groupId>
33 <artifactId>javax.servlet-api</artifactId>
34 <version>4.0.1</version>
35 </dependency>
36 <dependency>
37 <groupId>junit</groupId>
38 <artifactId>junit</artifactId>
39<!-- 通过 ${juint-version} 使用在属性配置中自定义的变量-->
40 <version>${juint-version}</version>
41<!-- 依赖范围:compile、test、provided ,默认是compile-->
42 <scope>test</scope>
43 </dependency>
44 </dependencies>
45
46 <build>
47<!-- 指定资源文件,默认Maven 只会将资源目录下文件拷贝过去-->
48 <resources>
49 <resource>
50 <directory>src/main/java</directory>
51 <includes>
52 <include>**/*.xml</include>
53 </includes>
54 </resource>
55 </resources>
56 </build>
57</project>Maven settings.xml详解 ¶
1<?xml version="1.0" encoding="UTF-8"?>
2
3<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
6
7 <!-- 本地仓库地址 -->
8 <localRepository>F:/study/soft/mavenRepository</localRepository>
9
10 <!-- 是否提示输入,false时在需要输入时maven会自动
11 | Default: true
12 -->
13 <interactiveMode>true</interactiveMode>
14
15 <!-- maven在执行生成时是否应尝试连接到网络
16 | Default: false
17 -->
18 <offline>false</offline>
19
20 <!-- pluginGroups
21 | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
22 | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
23 | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
24 |-->
25 <pluginGroups>
26 <!-- pluginGroup
27 | Specifies a further group identifier to use for plugin lookup.
28 <pluginGroup>com.your.plugins</pluginGroup>
29 -->
30 </pluginGroups>
31
32 <!-- 代理配置 -->
33 <proxies>
34 <!-- proxy
35 | Specification for one proxy, to be used in connecting to the network.
36 |
37 <proxy>
38 <id>optional</id>
39 <active>true</active>
40 <protocol>http</protocol>
41 <username>proxyuser</username>
42 <password>proxypass</password>
43 <host>proxy.host.net</host>
44 <port>80</port>
45 <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
46 </proxy>
47 -->
48 </proxies>
49
50 <!-- 服务器认证配置 -->
51 <servers>
52 <!-- server
53 <server>
54 <id>deploymentRepo</id>
55 <username>repouser</username>
56 <password>repopwd</password>
57 </server>
58 -->
59
60 <!-- Another sample, using keys to authenticate.
61 <server>
62 <id>siteServer</id>
63 <privateKey>/path/to/private/key</privateKey>
64 <passphrase>optional; leave empty if not used.</passphrase>
65 </server>
66 -->
67 </servers>
68
69 <!-- mirrors 镜像仓库,
70 | mirrorOf 设置为 central 表示去中央仓库下载时通过下面这个地址
71 | profile 默认包含了一个 central 配置
72 | 仓库查找顺序 按照 profile 中配置仓库依次查找,如果都没有就走 central
73 -->
74 <mirrors>
75 <mirror>
76 <id>aliyunmaven</id>
77 <mirrorOf>central</mirrorOf>
78 <name>阿里云公共仓库</name>
79 <url>https://maven.aliyun.com/repository/public</url>
80 </mirror>
81 </mirrors>
82
83 <profiles>
84 <!-- profile
85 | Specifies a set of introductions to the build process, to be activated using one or more of the
86 | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
87 | or the command line, profiles have to have an ID that is unique.
88 |
89 | An encouraged best practice for profile identification is to use a consistent naming convention
90 | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
91 | This will make it more intuitive to understand what the set of introduced profiles is attempting
92 | to accomplish, particularly when you only have a list of profile id's for debug.
93 |
94 | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
95 <profile>
96 <id>jdk-1.4</id>
97
98 <activation>
99 <jdk>1.4</jdk>
100 </activation>
101
102 <repositories>
103 <repository>
104 <id>jdk14</id>
105 <name>Repository for JDK 1.4 builds</name>
106 <url>http://www.myhost.com/maven/jdk14</url>
107 <layout>default</layout>
108 <snapshotPolicy>always</snapshotPolicy>
109 </repository>
110 </repositories>
111 </profile>
112 -->
113
114 <profile>
115 <id>tencentyunmaven</id>
116 <repositories>
117 <repository>
118 <id>nexus-tencentyun</id>
119 <name>Nexus tencentyun</name>
120 <url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
121 <layout>default</layout>
122 <releases>
123 <enabled>true</enabled>
124 </releases>
125 <snapshots>
126 <enabled>true</enabled>
127 </snapshots>
128 </repository>
129 </repositories>
130 <pluginRepositories>
131 <pluginRepository>
132 <id>nexus-tencentyun</id>
133 <name>Nexus tencentyun</name>
134 <url>https://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
135 <releases>
136 <enabled>true</enabled>
137 </releases>
138 <snapshots>
139 <enabled>true</enabled>
140 </snapshots>
141 </pluginRepository>
142 </pluginRepositories>
143 </profile>
144 <profile>
145 <id>aliyunmaven</id>
146 <!-- 默认激活该配置, 如果存在其他任意激活配置, 该配置失效 -->
147 <activation>
148 <activeByDefault>true</activeByDefault>
149 </activation>
150 <repositories>
151 <repository>
152 <id>aliyunmaven</id>
153 <name>阿里云公共仓库</name>
154 <url>https://maven.aliyun.com/repository/public/</url>
155 <releases>
156 <enabled>true</enabled>
157 </releases>
158 <snapshots>
159 <enabled>true</enabled>
160 </snapshots>
161 </repository>
162 </repositories>
163 <pluginRepositories>
164 <pluginRepository>
165 <id>aliyunmaven</id>
166 <name>阿里云公共仓库</name>
167 <url>https://maven.aliyun.com/repository/public/</url>
168 <releases>
169 <enabled>true</enabled>
170 </releases>
171 <snapshots>
172 <enabled>true</enabled>
173 </snapshots>
174 </pluginRepository>
175 </pluginRepositories>
176 </profile>
177 </profiles>
178
179 <!-- 激活的 Profile -->
180 <activeProfiles>
181 <activeProfile>tencentyunmaven</activeProfile>
182 </activeProfiles>
183
184</settings>war 包名带时间戳 ¶
方式一
在 Maven 中,要让打包后的 WAR 文件名自动带上“日期”,可以通过配置 maven-war-plugin 的 <finalName> 来实现,结合 Maven 的 maven.build.timestamp 属性即可
在 pom.xml 中添加或修改如下配置
1<properties>
2 <!-- 定义时间格式 -->
3 <maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
4 <!-- 如果你想带 时间戳(小时分钟),把时间格式改为 yyyyMMdd_HHmm -->
5 <!-- 强制使用东八区,Maven 版本 ≥ 3.9 -->
6 <maven.build.timestamp.timezone>Asia/Shanghai</maven.build.timestamp.timezone>
7</properties>
8
9<build>
10 <finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}</finalName>
11 <plugins>
12 <plugin>
13 <groupId>org.apache.maven.plugins</groupId>
14 <artifactId>maven-war-plugin</artifactId>
15 <version>3.3.2</version> <!-- 用最新版 -->
16 <configuration>
17 <!-- 确保使用上面定义的 finalName -->
18 <warName>${project.artifactId}-${project.version}-${maven.build.timestamp}</warName>
19 </configuration>
20 </plugin>
21 </plugins>
22</build>注意事项:
maven.build.timestamp是 Maven 内置变量,只在构建时有效,不会影响源码中任何地方生成的时间默认为UTC时区的,会相差8小时,maven3.9以上版本可以通过配置强制使用东八区
如果你使用的是 Spring Boot 的
spring-boot-maven-plugin,它默认会忽略finalName,需要额外配置xml1<plugin> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-maven-plugin</artifactId> 4 <configuration> 5 <finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}</finalName> 6 </configuration> 7</plugin>
方式二
用插件动态生成时间(兼容所有 Maven 版本),引入 build-helper-maven-plugin,在打包前把东八区时间写入属性,再供 finalName 使用。
| 配置项 | 含义 |
|---|---|
groupId / artifactId / version | 插件坐标,确保使用的是 3.4.0 版本 |
execution.id | 命名为 timestamp-property,可自定义 |
phase | 绑定到 validate 阶段,即构建一开始就会执行 |
goal | 使用 timestamp-property 目标来生成时间戳属性 |
configuration.name | 生成的 Maven 属性名,这里是 build.time |
configuration.pattern | 时间格式,yyyyMMdd_HHmm 会生成如 20250812_1432 |
configuration.timeZone | 指定时区为 Asia/Shanghai,即中国标准时间 |
1<build>
2 <finalName>${project.artifactId}-${project.version}-${build.time}</finalName>
3 <plugins>
4 <!-- 1. 生成东八区时间 -->
5 <plugin>
6 <groupId>org.codehaus.mojo</groupId>
7 <artifactId>build-helper-maven-plugin</artifactId>
8 <version>3.4.0</version>
9 <executions>
10 <execution>
11 <id>timestamp-property</id>
12 <phase>validate</phase>
13 <goals><goal>timestamp-property</goal></goals>
14 <configuration>
15 <name>build.time</name>
16 <pattern>yyyyMMdd_HHmm</pattern>
17 <timezone>Asia/Shanghai</timezone>
18 </configuration>
19 </execution>
20 </executions>
21 </plugin>
22
23 <!-- 2. 打 war 包时使用上面的时间 -->
24 <plugin>
25 <groupId>org.apache.maven.plugins</groupId>
26 <artifactId>maven-war-plugin</artifactId>
27 <version>3.3.2</version>
28 <configuration>
29 <warName>${project.artifactId}-${project.version}-${build.time}</warName>
30 </configuration>
31 </plugin>
32 </plugins>
33</build>