Maven 项目管理

2020-11-07 约 5970 字 阅读时长12 分钟

Maven

Maven基础

  • Maven可以管理jar文件
  • 自动下载jar和他的文档,源代码
  • 管理jar的直接依赖
  • 管理所需要的jar文件版本
  • 测试代码是否正确
  • 打包文件,形成jar文件,或war文件
  • 部署项目

构建:项目的构建

  1. 清理,把之前项目编译的东西删除掉
  2. 编译,把程序源代码编译成可执行代码,批量的
  3. 测试,Maven执行多个测试代码,验证程序是否正确,批量的
  4. 报告,生成测试结果文件,测试是否通过
  5. 打包,将项目所有文件资源打包到一个压缩文件中;对于通常的java程序,文件扩展名为jar;对于web应用,文件扩展名为war
  6. 安装,把步骤五打包的文件jar或war安装到本地仓库
  7. 部署

Maven核心概念

  1. POM:一个文件,名称是 pom.xml ,pom翻译过来就是项目对象模型;控制Maven构建项目过程,管理jar依赖
  2. 约定目录结构:Maven项目目录结构是规定的
  3. 坐标:唯一字符串,用于表示资源的
  4. 依赖管理:管理项目 jar 文件
  5. 仓库管理
  6. 生命周期
  7. 插件和目标
  8. 继承
  9. 聚合

Maven安装与配置

  1. 从 apache 官网下载 Maven 安装包
  2. 配置国内仓库,提升 Maven 速度
  3. 环境变量配置
  4. mvn -v 验证是否配置成功

Maven 核心

Maven 约定的目录结构

一个使用Maven管理的普通的Java项目,它的目录结构默认如下:

ascii
 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.xmlMaven的灵魂,它的内容长得像下面:

xml
 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工程就是由groupIdartifactIdversion作为唯一标识。我们在引用其他第三方库的时候,也是通过这3个变量确定。例如,依赖commons-logging

xml
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定义了几种依赖关系,分别是compiletestruntimeprovided

scope说明示例
compile编译时需要用到该jar包(默认)commons-logging
test编译Test时需要用到该jar包junit
runtime编译时不需要,但运行时需要用到mysql
provided编译时需要用到,但运行时由JDK或某个服务器提供servlet-api

test依赖表示仅在测试时使用,正常运行时并不需要。最常用的test依赖就是JUnit:

xml
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,如何确切地获得它的groupIdartifactIdversion?方法是通过search.Maven.org搜索关键字,找到对应的组件后,直接复制

小结

  • Maven通过解析依赖关系确定项目所需的jar包,常用的4种scope有:compile(默认),testruntimeprovided
  • Maven从中央仓库下载所需的jar包并缓存在本地
  • 可以通过镜像仓库加速下载

构建流程(生命周期)

构建流程

Maven 不但有标准化的项目结构,而且还有一套标准化的构建流程,可以自动化实现编译、打包、发布等等

Lifecycle 和 Phase

Maven的生命周期由一系列阶段(phase)构成

使用mvn这个命令时,后面的参数是phase,Maven自动根据生命周期运行到指定的phase

实际开发过程中,经常使用的命令有:

  • mvn clean:清理所有生成的class和jar
  • mvn clean compile:先清理,再执行到compile
  • mvn clean test:先清理,再执行到test,因为执行test前必须执行compile,所以这里不必指定compile
  • mvn clean package:先清理,再执行到package

大多数phase在执行过程中,因为我们通常没有在pom.xml中配置相关的设置,所以这些phase什么事情都不做

经常用到的phase其实只有几个:

  • clean:清理
  • compile:编译
  • test:运行测试
  • package:打包

Goal

执行一个phase又会触发一个或多个goal:

执行的Phase对应执行的Goal
compilecompiler:compile
testcompiler: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是最小任务单元。

例如执行以下命令

shell
1mvn compile

Maven 将执行 compile 这个 phase,这个 phase 会调用 compiler 插件执行关联的 compiler:compile 这个goal

实际上,执行每个phase,都是通过某个插件(plugin)来执行的,Maven本身其实并不知道如何执行compile,它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译。

分析

所以,使用Maven,实际上就是配置好需要使用的插件,然后通过phase调用它们。

Maven已经内置了一些常用的标准插件:

插件名称对应执行的phase
cleanclean
compilercompile
surefiretest
jarpackage

如果标准插件无法满足需求,我们还可以使用自定义插件。使用自定义插件的时候,需要声明。例如,使用Maven-shade-plugin可以创建一个可执行的jar,要使用这个插件,需要在pom.xml中声明它:

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程序的入口,它的配置是:

xml
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 ,一个专门测试的框架(工具);测试的基本单元是方法

  1. 在 pom.xml 中加入依赖项

    xml
    1        <dependency>
    2            <groupId>junit</groupId>
    3            <artifactId>junit</artifactId>
    4            <version>4.12</version>
    5            <scope>test</scope>
    6        </dependency>
  2. 在 Maven 项目下的 src/test/java 目录下,创建测试程序

    • 测试类的名称 是 Test + 需要测试的类名
    • 测试方法的名称是 Test + 方法名
    java
     1//例如测试 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文件

xml
 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文件

xml
 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 文件

xml
 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详解

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 中添加或修改如下配置

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,需要额外配置

    xml
    1<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,即中国标准时间
xml
 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>
使用滚轮缩放
按住拖动