${project.version} 在 properties 中不生效,因其属于 Maven 模型层字段,在 properties 静态解析阶段尚未注入;只能在依赖、插件配置、version 标签等模型解析完成后的位置安全使用。

为什么 ${project.version} 在 properties 里不生效
因为 pom.xml 中的 <properties> 是静态解析阶段读取的,而 ${project.version} 属于“项目坐标变量”,在 properties 解析时还没被注入——它本质上是 model 层字段,不是 properties 定义的占位符。
常见错误现象:<my.version>${project.version}</my.version> 被原样保留,后续用 ${my.version} 引用时得到空值或字面量字符串 ${project.version}。
- 不要在
<properties>块内直接引用${project.version}、${project.groupId}等 model 变量 - 如果只是想统一版本号,直接把值写死在
<properties>里(如<app.version>1.2.3</app.version>),再在<version>或依赖中引用它 - 若必须动态对齐
project.version,改用<version>${project.version}</version>直接写在对应模块声明处,而不是塞进 properties
哪些地方能安全用 ${project.version}
它只在 Maven 模型解析完成后的上下文中可用,比如依赖声明、插件配置、<version> 标签内部等。Maven 会按生命周期顺序填充这些字段。
使用场景举例:多模块项目中子模块想继承父 POM 的版本,又不想硬编码;或者插件配置里需要根据当前构建版本打 tag。
- ✅ 依赖中:
<version>${project.version}</version> - ✅ 插件配置中:
<configuration><finalName>app-${project.version}</finalName></configuration> - ✅
<version>标签本身(模块自身):<version>${project.version}</version>—— 这是合法且常见的做法 - ❌
<properties>块内:<api.version>${project.version}</api.version>—— 不会被解析
替代方案:用 flatten-maven-plugin 暴露 project 变量
如果你真需要把 project.version 注入到 properties(例如生成 flattened pom 供下游消费),得靠插件主动“拍平”模型字段。单纯靠原生 pom 语法做不到。
性能影响很小,但会增加构建步骤;兼容性上要求 Maven 3.2+,老项目需注意。
- 在
<build><plugins>中添加flatten-maven-plugin,配置<flattenMode>resolveCiFriendliesOnly</flattenMode> - 启用后,生成的
flattened-pom.xml里${project.version}会被替换成实际值,且可被其他工具读取 - 注意:这只是输出时的替换,不影响构建时的 properties 解析逻辑
最简实践:别绕弯,直接用 project.version 的原始位置
多数人想用 ${project.version} 在 properties 里,其实只是为了复用版本号。但 Maven 的设计本意就是让 <version> 成为唯一真相源——你不需要把它“复制”出去。
容易被忽略的一点:当你在父 POM 写了 <version>2.0.0</version>,所有子模块默认继承该值;此时子模块的 <version> 可以省略,也可以显式写成 ${project.version},Maven 都认。
- 子模块 pom 中,直接写
<version>${project.version}</version>即可,无需中间变量 - 依赖版本也优先从父 POM 的
<dependencyManagement>统一控制,而不是靠 properties 传参 - 如果用了 Spring Boot 或类似 BOM,更应避免手动同步版本,交给
spring-boot-dependencies管理
真正复杂的点从来不是怎么写这个变量,而是搞清它在哪一刻、被谁、以什么方式解析——写错位置,后面全白搭。










