Maven 的 build 是 POM 文件(pom.xml)中核心配置节点之一,用于定义项目构建的全生命周期行为(编译、打包、测试、部署等)。下面我会从「核心配置项」「常用子节点」「实战示例」三个维度,用通俗易懂的方式讲解关键配置,重点聚焦新手最常用的部分。
Maven build
一、build 核心结构
先看 build 节点的基础骨架,核心子节点如下:
xml
<project>
<!-- 其他配置(groupId/artifactId/version 等) -->
<build>
<!-- 1. 构建基础配置 -->
<defaultGoal>compile</defaultGoal>
<directory>target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
<!-- 2. 源码/资源文件配置 -->
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>...</resources>
<testResources>...</testResources>
<!-- 3. 插件配置(最核心) -->
<plugins>...</plugins>
<!-- 4. 插件管理(统一版本) -->
<pluginManagement>...</pluginManagement>
</build>
</project>
二、核心配置项详解
1. 基础构建配置(通用项)
| 配置项 | 作用 | 默认值 |
|---|---|---|
defaultGoal |
执行 mvn 无参数时默认触发的构建目标(如 compile/package) |
compile |
directory |
构建产物(class、jar 等)的输出根目录 | target |
finalName |
打包后的文件名(如 jar/war 包名),支持 Maven 内置变量 | ${project.artifactId}-${version} |
示例:自定义打包后的 jar 名
xml
<finalName>my-project-1.0.0-release</finalName>
<!-- 最终输出:target/my-project-1.0.0-release.jar -->
2. 源码/资源文件配置
用于指定源码、测试源码、资源文件的路径(默认路径满足 99% 场景,特殊情况才修改)。
sourceDirectory:主源码目录(Java 文件),默认src/main/javatestSourceDirectory:测试源码目录,默认src/test/javaresources:主资源文件目录(如application.yml、配置文件),默认src/main/resourcestestResources:测试资源文件目录,默认src/test/resources
实战场景:自定义资源文件路径+过滤资源变量
xml
<resources>
<resource>
<!-- 资源文件目录 -->
<directory>src/main/resources</directory>
<!-- 是否过滤资源文件中的 Maven 变量(如 ${project.version}) -->
<filtering>true</filtering>
<!-- 包含/排除指定文件 -->
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
</includes>
<excludes>
<exclude>**/*.log</exclude>
</excludes>
</resource>
</resources>
3. 插件配置(<plugins>,最核心)
Maven 的所有构建行为(编译、打包、运行)都依赖插件,<plugins> 是 build 中最常用的节点,用于配置插件的版本、参数、执行目标。
高频插件示例
(1)编译插件(maven-compiler-plugin)
指定 Java 编译版本(解决「源码使用了更高版本 Java 特性」报错):
xml
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version> <!-- 推荐指定版本,避免默认版本兼容问题 -->
<configuration>
<source>1.8</source> <!-- 源码编译版本(Java 8) -->
<target>1.8</target> <!-- 生成的 class 文件兼容版本 -->
<encoding>UTF-8</encoding> <!-- 解决中文乱码 -->
</configuration>
</plugin>
</plugins>
(2)打包插件(maven-jar-plugin/maven-war-plugin)
自定义 jar 包的 MANIFEST.MF(如指定主类、依赖):
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath> <!-- 包含依赖类路径 -->
<classpathPrefix>lib/</classpathPrefix> <!-- 依赖存放目录 -->
<mainClass>com.example.MyMainClass</mainClass> <!-- 可执行 jar 的主类 -->
</manifest>
</archive>
</configuration>
</plugin>
(3)打包可执行胖包(maven-shade-plugin)
将所有依赖打包到一个 jar 包(解决「运行时找不到依赖」问题):
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase> <!-- 在 package 阶段执行 -->
<goals>
<goal>shade</goal> <!-- 执行 shade 目标 -->
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.MyMainClass</mainClass> <!-- 主类 -->
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
4. 插件版本管理(<pluginManagement>)
用于统一管理插件版本(避免多模块项目中重复指定版本),仅定义版本,不执行插件;子模块可直接引用,无需再指定版本。
示例:父 POM 中统一管理插件版本
xml
<build>
<pluginManagement>
<plugins>
<!-- 定义编译插件版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<!-- 定义打包插件版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
<!-- 子模块/当前项目引用时,无需指定版本 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
三、常见实战配置示例
示例 1:Java 8 项目基础构建配置
xml
<build>
<finalName>my-app-1.0.0</finalName>
<plugins>
<!-- 编译配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 打包可执行 jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
示例 2:多模块项目统一插件版本
xml
<!-- 父 POM -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<!-- 子模块 POM -->
<build>
<plugins>
<!-- 直接引用父 POM 定义的插件,无需版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
总结
build核心作用是定义 Maven 构建规则,最关键的是<plugins>(插件配置)和<pluginManagement>(版本统一);- 新手优先掌握「编译插件(指定 Java 版本)」「打包插件(自定义 jar 名/主类)」,解决 80% 的构建问题;
resource节点用于管理资源文件,开启filtering=true可替换资源中的 Maven 变量;- 多模块项目务必用
pluginManagement统一插件版本,避免版本冲突。
Maven 内置属性
一、${basedir} 核心解析
${basedir} 是 Maven 最常用的内置属性之一,代表当前项目的根目录(即包含 pom.xml 文件的那个文件夹),是 Maven 路径相关操作的核心变量,无需手动定义即可直接使用。
1. 基础用法示例
xml
<?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>com.example</groupId>
<artifactId>demo-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<build>
<!-- 示例1:指定资源文件目录(默认就是basedir/src/main/resources,此处仅演示) -->
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<!-- 示例2:插件中指定文件路径 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- 打印项目根目录路径 -->
<echo>项目根目录:${basedir}</echo>
<!-- 引用根目录下的自定义文件 -->
<copy file="${basedir}/custom-config.properties" tofile="${project.build.directory}/config.properties"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. 核心特性
- 路径基准 :所有相对路径在 Maven 中默认以
${basedir}为基准,比如src/main/java等价于${basedir}/src/main/java; - 多模块适配 :在多模块项目中,父模块的
${basedir}是父 pom 所在目录,子模块的${basedir}是子模块自身的根目录(子模块 pom 所在目录); - 不可修改:该值由 Maven 自动识别,无法通过 POM 手动赋值修改。
二、Maven 常用内置属性(系统/项目属性)
Maven 内置属性分为两类:项目核心属性 (和当前项目强相关)、环境/系统属性(和运行环境相关),以下是开发中高频使用的内置属性,无需手动定义即可直接使用:
1. 项目核心属性(最常用)
| 属性名 | 含义 |
|---|---|
${project.version} |
当前项目的版本号(即 pom 中 <version> 的值) |
${project.groupId} |
当前项目的 GroupId(即 pom 中 <groupId> 的值) |
${project.artifactId} |
当前项目的 ArtifactId(即 pom 中 <artifactId> 的值) |
${project.name} |
当前项目的名称(pom 中 <name> 的值,未声明则默认 groupId:artifactId) |
${project.packaging} |
项目打包类型(pom/jar/war/ear 等,默认 jar) |
${basedir} |
当前项目根目录(pom.xml 所在目录) |
${project.build.directory} |
项目构建输出目录(默认 ${basedir}/target) |
${project.build.sourceDirectory} |
主源码目录(默认 ${basedir}/src/main/java) |
${project.build.testSourceDirectory} |
测试源码目录(默认 ${basedir}/src/test/java) |
${project.build.outputDirectory} |
编译后的类文件输出目录(默认 ${target}/classes) |
${project.version} |
同 ${project.version},简写形式,效果一致 |
2. 构建路径相关属性
| 属性名 | 含义 |
|---|---|
${project.build.finalName} |
项目打包后的最终文件名(默认 ${artifactId}-${version},如 demo-1.0.0) |
${project.resources} |
主资源文件目录(默认 ${basedir}/src/main/resources) |
${project.testResources} |
测试资源文件目录(默认 ${basedir}/src/test/resources) |
${project.build.scriptSourceDirectory} |
脚本源码目录(默认 ${basedir}/src/main/scripts) |
3. 环境/系统属性(和运行环境相关)
| 属性名 | 含义 |
|---|---|
${user.home} |
当前操作系统登录用户的主目录(如 Windows 下 C:\Users\用户名,Linux 下 /home/用户名) |
${user.dir} |
Maven 命令执行的当前目录(注意:不一定等于 ${basedir},若在子目录执行 mvn 命令则不同) |
${java.home} |
JDK 安装目录(如 C:\Program Files\Java\jdk1.8.0_301) |
${java.version} |
当前使用的 JDK 版本(如 1.8.0_301) |
${os.name} |
操作系统名称(如 Windows 10、Linux) |
${file.separator} |
系统文件分隔符(Windows 是 \,Linux/Mac 是 /) |
${path.separator} |
系统路径分隔符(Windows 是 ;,Linux/Mac 是 :) |
${line.separator} |
系统换行符(Windows 是 \r\n,Linux/Mac 是 \n) |
4. 实用示例:组合使用内置属性
xml
<!-- 示例:自定义打包后的文件名和输出路径 -->
<build>
<!-- 最终打包文件名:demo-1.0.0-release -->
<finalName>${project.artifactId}-${project.version}-release</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<!-- 输出目录:项目根目录/build/libs -->
<outputDirectory>${basedir}/build/libs</outputDirectory>
<!-- 包含JDK版本信息 -->
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<implementationVersion>${java.version}</implementationVersion>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
三、总结
${basedir}是 Maven 内置属性,代表当前项目根目录(pom.xml 所在目录),是路径配置的核心基准;- Maven 内置属性分项目属性 (如
${project.version}/${basedir})和系统属性 (如${user.home}/${java.version}),无需手动定义即可直接使用; - 核心价值是统一配置、适配环境,避免硬编码路径/版本/环境信息,提升 POM 灵活性和可维护性。