Maven 屬性系統是構建靈活性的核心,支援在 POM、Settings、命令列、環境變數等多個層面定義與引用變數。掌握屬性分類、優先級與解析機制,能讓構建配置更乾淨、可移植、易維護。
Maven 核心預定義,無需聲明即可直接使用:
| 屬性 | 含義 | 範例值 |
|---|---|---|
${basedir} | 專案根目錄 (含 pom.xml 的目錄) | /home/user/my-project |
${version} / ${project.version} | 專案版本 | 1.0.0-SNAPSHOT |
${project.basedir} | 同 ${basedir} | /home/user/my-project |
${maven.version} | Maven 版本 | 3.9.6 |
| 屬性 | 對應 POM 元素 | 預設值 |
|---|---|---|
${project.build.sourceDirectory} | <build><sourceDirectory> | src/main/java |
${project.build.testSourceDirectory} | <build><testSourceDirectory> | src/test/java |
${project.build.directory} | <build><directory> | target |
${project.build.outputDirectory} | <build><outputDirectory> | target/classes |
${project.build.testOutputDirectory} | <build><testOutputDirectory> | target/test-classes |
${project.groupId} | <groupId> | - |
${project.artifactId} | <artifactId> | - |
${project.version} | <version> | - |
${project.build.finalName} | <build><finalName> | ${project.artifactId}-${project.version} |
${project.packaging} | <packaging> | jar |
在 <properties> 區塊自定義,專案級全域常量:
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<docker.image.prefix>mycompany</docker.image.prefix>
<skipTests>false</skipTests>
</properties>
引用方式:${java.version}、${spring-boot.version}
對應 settings.xml 元素,採用 settings. 前綴:
${settings.localRepository}:本地倉庫路徑 (預設 ~/.m2/repository)${settings.offline}:離線模式開關${settings.proxies}、${settings.servers}、${settings.mirrors}:代理/伺服器/鏡像配置所有 System.getProperties() 可用屬性,無前綴直接引用:
| 屬性 | 含義 | 範例 |
|---|---|---|
${user.home} | 使用者家目錄 | /home/user |
${user.dir} | 當前工作目錄 | /home/user/project |
${java.home} | JRE 安裝目錄 | /usr/lib/jvm/java-17 |
${java.version} | Java 版本 | 17.0.9 |
${os.name} | 作業系統名稱 | Linux |
${file.encoding} | 檔案編碼 | UTF-8 |
所有作業系統環境變數,採用 env. 前綴:
${env.JAVA_HOME} → JAVA_HOME 環境變數值${env.PATH} → PATH 環境變數值${env.CI} → CI 環境標識 (GitHub Actions/GitLab CI 常設為 true)${env.BUILD_NUMBER} → Jenkins 建構編號mvn -DskipTests=true clean install<properties> 定義<properties> 繼承<properties>實戰技巧:命令列
-D參數可覆蓋所有層級屬性,是 CI/CD 動態注入版本號、環境標識的標準方式。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<docker.image.name>${docker.image.prefix}/${project.artifactId}</docker.image.name>
</properties>
<profiles>
<profile>
<id>prod</id>
<properties>
<env.name>production</env.name>
<db.url>jdbc:mysql://prod-db:3306/app</db.url>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env.name>development</env.name>
<db.url>jdbc:mysql://localhost:3306/app</db.url>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!-- 啟用屬性置換 -->
<includes><include>**/*.yml</include><include>**/*.properties</include></includes>
</resource>
</resources>
</build>
資源檔案中即可使用:app.version=${project.version}、build.time=${maven.build.timestamp}
需啟用 maven-build-timestamp 外掛或使用 maven-antrun-plugin:
${maven.build.timestamp}:預設格式 yyyyMMdd-HHmm<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format><properties>,配合 dependencyManagement${project.basedir}、${project.build.directory}spring.boot.version),避免與系統屬性衝突settings.xml <servers> 或環境變數注入help:effective-pom:mvn help:effective-pom 查看最終解析後的屬性值| 現象 | 可能原因 | 解決方案 |
|---|---|---|
屬性未解析顯示 ${xxx} | 拼寫錯誤、屬性未定義、未在支援屬性的元素中使用 | 檢查拼寫、確認屬性定義位置、確認元素支援屬性插值 |
| 環境變數取不到值 | 環境變數名大小寫、Maven 進程未繼承環境變數 | Linux 大小寫敏感、檢查 CI/CD 環境變數注入配置 |
| 資源檔案未置換 | 未啟用 <filtering>true</filtering>、檔案編碼不匹配 | 啟用 filtering、設定 project.build.sourceEncoding |
Maven 屬性系統看似簡單,實則是構建自動化的骨架。合理設計屬性體系,能讓專案從開發、測試到生產環境的構建過程實現真正的「一次編寫,到處構建」。