Maven属性替换

一、替换规则

参考:https://maven.apache.org/ref/3.8.4/maven-model-builder/

1)替换时间

属性替换发生在ModelBuilder构建effective pom时,主要流程包括:profile激活、合并重复依赖、profile注入、父pom解析直至super pom、父子pom模型继承合并、模型的属性替换(也称属性翻译,属性解释)。

也就是说属性替换发生在父子pom继承合并之后,含依赖继承合并、配置继承合并等。使用合并后的配置、内置配置、环境配置,进行pom中的变量替换。

2)优先级

pom中的变量${xxx}在替换时可能多个配置Context都含有,此时会依据以下顺序来获取。从下面的图可知,pom.xml中定义属性优先级比内置变量project.*低,无法覆盖它们。也就是说父pom中使用${project.version}声明的版本会依据子pom的版本来替换。

value evaluation result common examples
project.* - 内置属性 POM content (see POM reference) ${project.version} ${project.build.finalName} ${project.artifactId} ${project.build.directory}
project.basedir the directory containing the pom.xml file ${project.basedir}
project.baseUri the directory containing the pom.xml file as URI ${project.baseUri}
build.timestamp maven.build.timestamp the UTC timestamp of build start, in yyyy-MM-dd'T'HH:mm:ss'Z' default format, which can be overridden with maven.build.timestamp.format POM property ${maven.build.timestamp}
* - 命令行中-D属性 user properties, set from CLI with -Dproperty=value ${skipTests}
* - pom.xml中属性 model properties, such as project properties set in the pom ${any.key}
maven.home The path to the current Maven home. ${maven.home}
maven.version The version number of the current Maven execution (since 3.0.4). For example, “3.0.5“. ${maven.version}
maven.build.version The full build version of the current Maven execution (since 3.0.4). For example, “Apache Maven 3.2.2 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19T14:51:28+01:00)“. ${maven.build.version}
maven.repo.local The repository on the local machine Maven shall use to store installed and downloaded artifacts (POMs, JARs, etc). ${user.home}/.m2/repository
* Java system properties (see JDK reference) ${user.home} ${java.home}
env.* * environment variables ${env.PATH}
settings.* Local user settings (see settings reference) ${settings.localRepository}

二、示例

1)父Pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>person</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<properties>
<prop-1>parent</prop-1>
<prop-2>parent</prop-2>
</properties>
<dependencies>
<!-- 和子pom.xml保留一个进行测试,效果一样-->
<dependency>
<groupId>${prop-1}</groupId>
<artifactId>${prop-2}</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

2)当前pom.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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>person</artifactId>
<groupId>parent</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>son</artifactId>
<version>1.1.0-SNAPSHOT</version>
<properties>
<prop-1>son</prop-1>
<project.version>1.2.0-SNAPSHOT</project.version>
</properties>
<dependencies>
<dependency>
<groupId>${prop-1}</groupId> <!-- 当前pom覆盖父pom属性,prop-1 -->
<artifactId>${prop-2}</artifactId> <!-- 当前pom未定义,直接继承父pom属性,prop-2 -->
<version>${project.version}</version> <!-- 当前pom尝试覆盖内置属性,但是失败 -->
</dependency>
</dependencies>
</project>

3)在当前Pom所在工程执行mvn clean compile报错如下:

1
Could not find artifact son:parent:jar:1.1.0-SNAPSHOT

由此可看出最终生效的属性如下:

  • prop-1:当前pom属性,当前pom覆盖了父pom
  • prop-2:父pom属性,当前pom未定义该属性,继承自父pom
  • project.version:当前pom尝试覆盖优先级更高的内置属性,但是失败

# 参考

  1. 为什么我不能覆盖DependencyManagement导入的pom的版本

评论