1. 概述

Maven作为Java开发中广受欢迎的构建和依赖管理工具,不仅支持核心功能,还允许我们创建自定义属性。在实际开发中,属性文件常用于存储配置值,如何让Maven读取外部属性文件是本文要解决的问题。

本文将探讨如何在Maven构建过程中读取外部属性文件,并通过实际示例展示其应用场景。我们假设读者已具备Maven基础使用经验,因此将跳过Maven入门介绍,直接切入核心问题。

2. 问题场景

为清晰说明问题,我们创建一个简化版Maven项目结构:

.
├── pom.xml
├── props
│   └── user.properties
└── src
    └── main
        └── resources
            └── result.txt

项目特点:

  • 无Java代码(聚焦Maven配置)
  • 包含核心配置文件pom.xml
  • 资源目录下有result.txt模板文件
  • 外部属性文件位于props/user.properties

2.1. 属性文件内容

user.properties包含以下配置:

my.name=Kai
my.hobbies=Reading, Tennis, Football
my.signature=vim rocks

2.2. 模板文件设计

result.txt使用${...}占位符:

Greeting message: ${greeting}
-----------------------------
Username is ${my.name}
His hobbies are ${my.hobbies}
He came in and said: "${my.signature}"

2.3. 基础Maven配置

pom.xml中配置资源过滤:

<project>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>${maven.resources.version}</version>
                <configuration>
                    <outputDirectory>${project.build.outputDirectory}/filtered-result</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <greeting>Hi there, how are you</greeting>
    </properties>
</project>

关键配置说明:

  • ✅ 启用资源过滤(<filtering>true</filtering>
  • ✅ 指定输出目录为target/classes/filtered-result
  • ⚠️ 默认在process-resources阶段执行过滤

2.4. 当前构建结果

执行构建命令:

mvn clean process-resources

输出结果(仅替换内部属性):

Greeting message: Hi there, how are you
-----------------------------
Username is ${my.name}
His hobbies are ${my.hobbies}
He came in and said: "${my.signature}"

问题暴露:Maven无法识别外部属性文件中的属性值。接下来我们通过插件解决这个问题。

3. 使用Properties Maven Plugin

Properties Maven Plugin是处理外部属性文件的利器,它能在构建过程中动态加载属性值。

3.1. 插件配置方案

pom.xml中添加插件配置:

<project>
    <build>
        <plugins>
           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <version>${properties.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>initialize</phase>
                        <goals>
                            <goal>read-project-properties</goal>
                        </goals>
                        <configuration>
                            <files>
                                <file>${user.properties.file}</file>
                            </files>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <properties>
        <greeting>Hi there, how are you</greeting>
        <user.properties.file>props/user.properties</user.properties.file>
        <properties.plugin.version>1.2.1</properties.plugin.version>
    </properties>
</project>

配置要点:

  • ✅ 在initialize阶段执行属性加载(构建初期)
  • ✅ 通过内部属性user.properties.file指定文件路径
  • ✅ 版本号使用变量管理(推荐实践)

3.2. 构建验证

执行构建后观察日志:

[INFO] --- properties:1.2.1:read-project-properties (default) @ external-properties ---
[INFO] Loading 3 properties from File: /.../external-properties-file/props/user.properties

检查输出文件:

Greeting message: Hi there, how are you
-----------------------------
Username is Kai
His hobbies are Reading, Tennis, Football
He came in and said: "vim rocks"

效果确认:所有占位符被正确替换,包括外部属性文件中的值。

3.3. 动态属性文件方案

实际开发中常需动态切换属性文件(如不同环境配置)。我们创建新文件props/liam.properties

my.name=Liam
my.hobbies=Music, Football, Computer Games
my.signature=Maven rocks

通过命令行参数指定文件:

mvn -Duser.properties.file=props/liam.properties clean process-resources

构建日志显示加载新文件:

[INFO] Loading 3 properties from File: /.../external-properties-file/props/liam.properties

输出结果验证:

Greeting message: Hi there, how are you
-----------------------------
Username is Liam
His hobbies are Music, Football, Computer Games
He came in and said: "Maven rocks"

优势对比

  • 固定配置:适合稳定场景
  • 动态配置:适合多环境构建(开发/测试/生产)

4. 总结

通过Properties Maven Plugin,我们实现了:

  1. ✅ 外部属性文件的动态加载
  2. ✅ 与Maven资源过滤的无缝集成
  3. ✅ 支持命令行动态指定属性文件

这种方案特别适合需要环境隔离配置的项目,避免了在pom.xml中硬编码敏感信息。相比传统方案,其优势在于:

  • 配置与构建逻辑分离
  • 支持多环境灵活切换
  • 保持pom.xml的简洁性

完整示例代码可参考:GitHub仓库


原始标题:How to Read an External Properties File in Maven | Baeldung