源本科技 | 码上会

Maven 属性管理

2026/03/17
2
0

引言

在大型云原生项目中,配置文件和依赖版本的管理往往是一项繁琐且容易出错的工作。如果将数据库地址、版本号等配置“硬编码”在 pom.xml 或资源文件中,一旦环境变更或版本升级,就需要修改大量文件。

Maven 的属性管理机制提供了一套强大的变量系统。它允许开发者定义“一次”,并在项目的任何地方(pom.xml、资源文件、命令行)引用“多次”。这不仅极大地提升了配置的可维护性,还为实现“一套代码,多环境部署”奠定了坚实基础。


自定义属性

自定义属性是用户在 pom.xml<properties> 标签中定义的键值对。它们本质上是 Maven 项目中的变量

核心作用

  • 版本统一控制:这是最常见的用法。在父工程中统一定义所有依赖的版本号,子模块引用时只需使用变量。升级版本时,只需修改父工程的一处定义。

  • 配置复用:对于重复出现的配置项(如编码格式、JDK 版本),定义一次即可全局生效。

  • 环境隔离:结合 Profile(profiles),可以为不同环境(开发、测试、生产)定义不同的属性值。

定义与引用

定义位置:通常在父工程的 pom.xml 中定义,以便所有子模块继承。

<project>
    <!-- ... 其他配置 ... -->
    
    <properties>
        <!-- 依赖版本管理 -->
        <spring.boot.version>3.1.5</spring.boot.version>
        <mysql.driver.version>8.0.33</mysql.driver.version>
        <lombok.version>1.18.30</lombok.version>
        
        <!-- 编译配置 -->
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>
    
    <!-- ... 其他配置 ... -->
</project>

引用方式:使用 ${属性名} 语法。

<dependencies>
    <!-- 引用 Spring Boot 版本 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>
    
    <!-- 引用 MySQL 驱动版本 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>${mysql.driver.version}</version>
    </dependency>
</dependencies>

最佳实践:在云原生开发中,强烈建议将所有第三方库的版本号都提取为属性,并在父工程的 <properties><dependencyManagement> 中统一管理。


资源文件过滤

Maven 不仅允许在 pom.xml 中使用属性,还支持在构建过程中,将 pom.xml 中的属性值替换到资源文件(如 .properties, .yaml, .xml)中。这一功能被称为资源过滤

应用场景

  • 多环境配置:同一个 application.yml,在开发环境连接本地数据库,在生产环境连接集群数据库。

  • 版本注入:在配置文件中记录当前构建的项目版本号,便于运行时监控和日志追踪。

配置步骤

在 POM 中定义

可以在父工程定义默认值,也可以结合 <profiles> 为不同环境定义不同值。

<properties>
    <db.url>jdbc:mysql://localhost:3306/dev_db</db.url>
    <db.username>dev_user</db.username>
    <db.password>dev_pass</db.password>
    <app.version>${project.version}</app.version>
</properties>

开启资源过滤

pom.xml<build> 部分配置 <resources>,并将 filtering 设置为 true

<build>
    <resources>
        <resource>
            <!-- 指定资源目录 -->
            <directory>src/main/resources</directory>
            <!-- 开启过滤:Maven 会扫描文件并替换 ${...} 占位符 -->
            <filtering>true</filtering>
            <!-- 可选:只处理特定文件,避免二进制文件损坏 -->
            <includes>
                <include>**/*.properties</include>
                <include>**/*.yml</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

在资源文件中引用

src/main/resources/application.ymljdbc.properties 中直接使用占位符。

jdbc.properties 示例

# Maven 构建时,这些 ${...} 会被 pom.xml 中的实际值替换
jdbc.url=${db.url}
jdbc.username=${db.username}
jdbc.password=${db.password}
app.build.version=${app.version}

application.yml 示例

spring:
  datasource:
    url: ${db.url}
    username: ${db.username}
    password: ${db.password}

验证与调试

执行 mvn clean package 后,检查 target/classes 目录下的配置文件。你会发现 ${db.url} 已经被替换成了具体的 jdbc:mysql://... 字符串。

重要警告

  • 二进制文件过滤:不要对图片、字体、证书等二进制文件开启 filtering=true,这会导致文件损坏。务必在 <excludes> 中排除它们,或仅 include 文本文件。

  • 特殊字符转义:如果资源文件中本身需要保留 ${...} 格式(例如 Spring 的占位符 #{...} 或某些模板引擎语法),需要使用 Maven 的转义符号 @ 来包裹,如 @{spring.placeholder},或者更改 Maven 的过滤分隔符。


Maven 内置属性

除了自定义属性,Maven 还提供了丰富的内置属性,涵盖项目信息、系统环境、环境变量等。熟练掌握这些属性可以让配置更加灵活。

项目属性

引用 pom.xml 中对应的元素值。

  • ${project.groupId}:项目组织 ID

  • ${project.artifactId}:项目名称 ID

  • ${project.version}:项目版本(推荐用于资源文件中标记版本)

  • ${project.build.directory}:构建输出目录(通常是 target

  • ${project.basedir}:项目根目录绝对路径

系统属性

源自 JDK 的系统属性,通过 System.getProperties() 获取。

  • ${java.home}:Java 安装目录

  • ${user.home}:用户主目录

  • ${os.name}:操作系统名称

  • ${file.separator}:文件分隔符(Linux 为 /, Windows 为 \

环境变量属性

引用操作系统的的环境变量。必须加 env. 前缀

  • ${env.PATH}:系统 PATH 变量

  • ${env.JAVA_HOME}:Java _home 环境变量

  • ${env.USERNAME}:当前登录用户名

Settings 属性

源自 Maven 全局或用户级 settings.xml 配置。

  • ${settings.localRepository}:本地仓库路径

  • ${settings.offline}:是否离线模式

命令行属性

在执行 Maven 命令时通过 -D 参数传递的属性,优先级最高。

  • 用法mvn clean install -DskipTests -Dmy.custom.prop=value

  • 引用${my.custom.prop}

  • 场景:常用于 CI/CD 流水线中动态传入配置,无需修改代码。