Maven <pom.xml> 标签详尽教程

发布于:2025-08-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

先看一个最小 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>
    用途:指定打包类型(如 jarwarpomear)。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(默认)、providedruntimetestsystemimport(用于 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> 用于有变体的工件(例如 testssources),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>
    用途:定义不同环境/场景的构建变体(如 devprod、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 实战示例(组合)

  1. 最小可用 POM

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>0.1.0</version>
</project>
  1. 使用 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>

  1. 打包可执行 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)。

  • 谨慎使用资源过滤:默认会替换 ${...},若过滤错误可能破坏二进制文件(对资源目录做过滤时要小心仅过滤文本文件)。


网站公告

今日签到

点亮在社区的每一天
去签到