Maven <pom.xml> 标签详尽教程
先看一个最小 POM 模板(上下文)
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 其余标签见下方分类 -->
</project>
一、项目信息与标识(Project info)
<modelVersion>
用途:指定 POM 模型版本(目前恒为4.0.0
)。
示例:<modelVersion>4.0.0</modelVersion>
<groupId>
用途:组织或公司标识,类似 Java 包名前缀,组成坐标的一部分。
示例:<groupId>com.example</groupId>
<artifactId>
用途:模块/项目的名称(在同一 groupId 下唯一)。
示例:<artifactId>my-app</artifactId>
<version>
用途:项目版本(语义化版本或其它约定)。
示例:<version>1.0.0</version>
<packaging>
用途:指定打包类型(如jar
、war
、pom
、ear
)。jar
为默认。
示例:<packaging>jar</packaging>
<name>
、<description>
、<url>
用途:人类可读的项目名称、描述与项目主页(通常用于生成站点或 POM 元数据)。
示例:<name>My App</name> <description>A demo Maven project</description> <url>https://example.com/my-app</url>
<parent>
用途:继承自父 POM(用于共享版本/插件/配置)。子模块通过 parent 继承依赖管理、插件配置等。
示例:<parent><groupId>com.example</groupId><artifactId>parent-pom</artifactId><version>1.0.0</version> </parent>
<modules>
用途:多模块(multi-module)父 POM 使用,用于列出子模块目录。
示例:<modules><module>service-a</module><module>service-b</module> </modules>
<scm>
用途:源代码管理信息(用于mvn release
、site 等)。
示例:<scm><connection>scm:git:git://github.com/you/repo.git</connection><developerConnection>scm:git:ssh://github.com:you/repo.git</developerConnection><url>https://github.com/you/repo</url> </scm>
二、属性与版本管理(Properties & Versioning)
<properties>
用途:集中声明可复用的变量(版本号、编译参数、编码等),在 POM 中用${...}
引用。
示例:<properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencyManagement>
用途:在父 POM 中声明依赖的版本与范围等“默认值”,子模块只需声明 groupId/artifactId 即可继承版本,便于统一管理版本。注意:声明在 dependencyManagement 的依赖不会自动加入 classpath,仍需在<dependencies>
中引用。
示例:<dependencyManagement><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.0</version></dependency></dependencies> </dependencyManagement>
三、依赖相关标签(Dependencies)
<dependencies>
/<dependency>
用途:声明项目运行/编译/测试所需的库。每个<dependency>
包含groupId
,artifactId
,version
(除非由 dependencyManagement 管理)。
示例:<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.27</version></dependency> </dependencies>
<scope>
用途:指定依赖作用域:compile
(默认)、provided
、runtime
、test
、system
、import
(用于 BOM)。影响传递性与打包。
示例(测试依赖):<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope> </dependency>
<optional>
用途:标记依赖为“可选”,表示使用你的包的项目不会自动继承此依赖。
示例:<optional>true</optional>
<exclusions>
/<exclusion>
用途:排除某个传递依赖(避免冲突或不需要的传递包)。
示例(排除 Tomcat):<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions> </dependency>
<type>
/<classifier>
/<systemPath>
(不常用)
用途:<type>
指明构件类型(例如jar
/war
/zip
),<classifier>
用于有变体的工件(例如tests
、sources
),system
scope 需配合 systemPath(通常应避免使用)。
示例(classifier):<dependency><groupId>org.example</groupId><artifactId>lib</artifactId><version>1.0</version><classifier>tests</classifier> </dependency>
四、构建与插件(Build & Plugins)
<build>
用途:构建相关设置的根节点(finalName、plugins、resources 等)。
示例:<build><finalName>my-app</finalName> </build>
<finalName>
用途:构建输出的最终文件名(不含扩展名),例如target/my-app.jar
。
示例:<finalName>my-app-release</finalName>
<resources>
/<resource>
/<testResources>
用途:指定资源文件目录与过滤(resource filtering)。
示例(启用资源过滤):<resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource> </resources>
<plugins>
/<plugin>
用途:配置 Maven 插件(编译、打包、测试、发布等)。推荐始终指定插件版本以保证可重复构建。
示例(maven-compiler-plugin):<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins> </build>
<executions>
/<execution>
/<goals>
/<goal>
用途:设置插件在特定构建阶段执行的目标(可配置多个 execution)。
示例(shade 打包成 fat-jar):<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.example.Main</mainClass></transformer></transformers></configuration></execution></executions> </plugin>
<pluginManagement>
用途:在父 POM 中集中声明插件版本/配置的默认值,子模块可以继承或覆盖。与dependencyManagement
类似,但针对插件。
示例:<pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version></plugin></plugins> </pluginManagement>
五、Profiles(构建配置切换)
<profiles>
/<profile>
用途:定义不同环境/场景的构建变体(如dev
、prod
、CI)。profile 可以修改依赖、插件配置、properties 等;可通过命令行-P
激活或通过激活条件自动启用。
示例(按属性激活的 profile):<profiles><profile><id>prod</id><activation><property><name>env</name><value>prod</value></property></activation><properties><app.env>production</app.env></properties></profile> </profiles>
激活方式:
mvn clean package -Denv=prod
六、仓库与发布(Repositories & Distribution)
<repositories>
/<repository>
用途:声明构件下载仓库(除了默认 Maven Central,可声明私服或公司内网仓库)。
示例:<repositories><repository><id>company-repo</id><url>https://repo.example.com/maven2</url></repository> </repositories>
<pluginRepositories>
用途:为插件下载指定仓库(插件也需要仓库来源)。
示例:<pluginRepositories><pluginRepository><id>company-plugins</id><url>https://repo.example.com/plugins</url></pluginRepository> </pluginRepositories>
<distributionManagement>
用途:配置发布(deploy)目标仓库(release 和 snapshot 分开)。发布凭据和服务器 id 通常在~/.m2/settings.xml
中配置。
示例:<distributionManagement><repository><id>releases</id><url>https://repo.example.com/releases</url></repository><snapshotRepository><id>snapshots</id><url>https://repo.example.com/snapshots</url></snapshotRepository> </distributionManagement>
注意:不要在 POM 中把凭据写明,安全凭据放
settings.xml
。
七、元数据(开发者、许可证、CI、问题跟踪)
<developers>
/<developer>
用途:记录项目开发者信息(名字、邮箱、id),用于项目文档与站点。
示例:<developers><developer><id>alice</id><name>Alice Zhang</name><email>alice@example.com</email></developer> </developers>
<licenses>
/<license>
用途:声明项目使用的开源许可证(便于遵从性检查)。
示例:<licenses><license><name>Apache License, Version 2.0</name><url>http://www.apache.org/licenses/LICENSE-2.0.txt</url></license> </licenses>
<ciManagement>
、<issueManagement>
、<mailingLists>
用途:CI 服务、问题跟踪、邮件列表的元信息(主要用于 site/发布)。示例略。
八、典型 POM 实战示例(组合)
最小可用 POM
<project ...><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.1.0</version>
</project>
使用 properties + dependencyManagement 的父 POM(片段)
<project ...><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>parent</artifactId><version>1.0.0</version><packaging>pom</packaging><properties><java.version>17</java.version><jackson.version>2.15.0</jackson.version></properties><dependencyManagement><dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency></dependencies></dependencyManagement><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version></plugin></plugins></pluginManagement>
</project>
子模块可以只写 <dependency>
而不写 <version>
。
打包可执行 fat-jar(关键插件片段)
<build><plugins><!-- 编译 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin><!-- 打包成可执行 jar --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><createDependencyReducedPom>true</createDependencyReducedPom><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.example.Main</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins>
</build>
九、最佳实践与常见陷阱
统一版本管理:尽量在父 POM 使用
<dependencyManagement>
或<properties>
管理版本,避免子模块间依赖冲突。总是指定插件版本:不显式指定插件版本会导致不同环境构建结果不一致。
避免
system
scope:system 依赖不可移植,应使用私服或安装到本地仓库。不要把凭据写进 POM:发布仓库的用户名/密码放在
~/.m2/settings.xml
(server 节点)中。使用
mvn help:effective-pom
:查看合并后实际生效的 POM(包含继承与 profile)。谨慎使用资源过滤:默认会替换
${...}
,若过滤错误可能破坏二进制文件(对资源目录做过滤时要小心仅过滤文本文件)。