先看一个最小 POM 模板(上下文)
XML
<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)。示例:
XML<modelVersion>4.0.0</modelVersion> -
<groupId>用途:组织或公司标识,类似 Java 包名前缀,组成坐标的一部分。
示例:
XML<groupId>com.example</groupId> -
<artifactId>用途:模块/项目的名称(在同一 groupId 下唯一)。
示例:
XML<artifactId>my-app</artifactId> -
<version>用途:项目版本(语义化版本或其它约定)。
示例:
XML<version>1.0.0</version> -
<packaging>用途:指定打包类型(如
jar、war、pom、ear)。jar为默认。示例:
XML<packaging>jar</packaging> -
<name>、<description>、<url>用途:人类可读的项目名称、描述与项目主页(通常用于生成站点或 POM 元数据)。
示例:
XML<name>My App</name> <description>A demo Maven project</description> <url>https://example.com/my-app</url> -
<parent>用途:继承自父 POM(用于共享版本/插件/配置)。子模块通过 parent 继承依赖管理、插件配置等。
示例:
XML<parent> <groupId>com.example</groupId> <artifactId>parent-pom</artifactId> <version>1.0.0</version> </parent> -
<modules>用途:多模块(multi-module)父 POM 使用,用于列出子模块目录。
示例:
XML<modules> <module>service-a</module> <module>service-b</module> </modules> -
<scm>用途:源代码管理信息(用于
mvn release、site 等)。示例:
XML<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 中用
${...}引用。示例:
XML<properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> -
<dependencyManagement>用途:在父 POM 中声明依赖的版本与范围等"默认值",子模块只需声明 groupId/artifactId 即可继承版本,便于统一管理版本。注意:声明在 dependencyManagement 的依赖不会自动加入 classpath,仍需在
<dependencies>中引用。示例:
XML<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 管理)。示例:
XML<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)。影响传递性与打包。示例(测试依赖):
XML<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> -
<optional>用途:标记依赖为"可选",表示使用你的包的项目不会自动继承此依赖。
示例:
XML<optional>true</optional> -
<exclusions>/<exclusion>用途:排除某个传递依赖(避免冲突或不需要的传递包)。
示例(排除 Tomcat):
XML<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),systemscope 需配合 systemPath(通常应避免使用)。示例(classifier):
XML<dependency> <groupId>org.example</groupId> <artifactId>lib</artifactId> <version>1.0</version> <classifier>tests</classifier> </dependency>
四、构建与插件(Build & Plugins)
-
<build>用途:构建相关设置的根节点(finalName、plugins、resources 等)。
示例:
XML<build> <finalName>my-app</finalName> </build> -
<finalName>用途:构建输出的最终文件名(不含扩展名),例如
target/my-app.jar。示例:
XML<finalName>my-app-release</finalName> -
<resources>/<resource>/<testResources>用途:指定资源文件目录与过滤(resource filtering)。
示例(启用资源过滤):
XML<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> -
<plugins>/<plugin>用途:配置 Maven 插件(编译、打包、测试、发布等)。推荐始终指定插件版本 以保证可重复构建。
示例(maven-compiler-plugin):
XML<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):
XML<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类似,但针对插件。示例:
XML<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):
XML<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,可声明私服或公司内网仓库)。
示例:
XML<repositories> <repository> <id>company-repo</id> <url>https://repo.example.com/maven2</url> </repository> </repositories> -
<pluginRepositories>用途:为插件下载指定仓库(插件也需要仓库来源)。
示例:
XML<pluginRepositories> <pluginRepository> <id>company-plugins</id> <url>https://repo.example.com/plugins</url> </pluginRepository> </pluginRepositories> -
<distributionManagement>用途:配置发布(deploy)目标仓库(release 和 snapshot 分开)。发布凭据和服务器 id 通常在
~/.m2/settings.xml中配置。示例:
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),用于项目文档与站点。
示例:
XML<developers> <developer> <id>alice</id> <name>Alice Zhang</name> <email>alice@example.com</email> </developer> </developers> -
<licenses>/<license>用途:声明项目使用的开源许可证(便于遵从性检查)。
示例:
XML<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
XML
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.1.0</version>
</project>
- 使用 properties + dependencyManagement 的父 POM(片段)
XML
<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(关键插件片段)
XML
<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>管理版本,避免子模块间依赖冲突。 -
总是指定插件版本:不显式指定插件版本会导致不同环境构建结果不一致。
-
避免
systemscope:system 依赖不可移植,应使用私服或安装到本地仓库。 -
不要把凭据写进 POM :发布仓库的用户名/密码放在
~/.m2/settings.xml(server 节点)中。 -
使用
mvn help:effective-pom:查看合并后实际生效的 POM(包含继承与 profile)。 -
谨慎使用资源过滤 :默认会替换
${...},若过滤错误可能破坏二进制文件(对资源目录做过滤时要小心仅过滤文本文件)。