先看一个最小 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.0
http://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)。谨慎使用资源过滤:默认会替换
${...}
,若过滤错误可能破坏二进制文件(对资源目录做过滤时要小心仅过滤文本文件)。