跳过正文
  1. 文章/
  2. Java/
  3. JavaEE/
  4. Maven/

3、pom.xml

·4488 字·9 分钟· loading · loading · ·
Java JavaEE Maven
GradyYoung
作者
GradyYoung
Maven - 点击查看当前系列文章
§ 3、pom.xml 「 当前文章 」

POM
#

POM(项目对象模型)是 Maven 最基本,也是非常重要的一个概念。通常情况下,我们可以看到 POM 的表现形式是pom.xml,在这个 XML 文件中定义着关于我们工程的方方面面,当我们想要通过 Maven 命令来进行操作的时候,例如:编译,打包等等,Maven 都会从pom.xml文件中来读取工程相关的信息。

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>

  <!-- 基本配置 -->
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>

  <!-- 项目信息配置 -->
  <name>...</name>
  <description>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>

  <!-- 环境配置 -->
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
    
  <!-- 构建配置 -->
  <build>...</build>
  <reporting>...</reporting>
</project>

基本配置
#

project
#

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">
</project>

modelVersion
#

指定pom.xml符合哪个版本的描述符。maven 2 和 3 只能为4.0.0

<modelVersion>4.0.0</modelVersion>

Maven坐标
#

  • groupId:团体、组织的标识符。团体标识的约定是:它以创建这个项目的组织名称的逆向域名(reverse domain name)开头,一般对应着 java 的包结构。
  • artifactId:单独项目的唯一标识符。比如我们的 tomcat、commons 等。不要在artifactId中包含点号.
  • version:项目的特定版本,maven 在版本管理时候可以使用几个特殊的字符串SNAPSHOT、LATEST、RELEASE,例如:1.0-SNAPSHOT
    • SNAPSHOT:这个版本一般用于开发过程中,表示不稳定的版本。
    • LATEST:指某个特定构件的最新发布,这个发布可能是一个发布版,也可能是一个snapshot版,具体看哪个时间最后。
    • RELEASE:指最后一个发布版。
<groupId>top.ygang</groupId>
<artifactId>demo</artifactId>
<version>1.0</version>

packaging
#

项目的类型,描述了项目打包后的输出,默认是jar,常见的输出类型如下:pomjarmaven-pluginejbwarearrarpar

<packaging>jar</packaging>

dependencies
#

指定项目的所有依赖结构

<dependencies>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-embedder</artifactId>
        <version>2.0</version>
        <type>jar</type>
        <scope>test</scope>
        <optional>true</optional>
        <exclusions>
            <exclusion>
                <groupId>org.apache.maven</groupId>
                <artifactId>maven-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>top.ygang</groupId>
        <artifactId>myjar</artifactId>
        <version>1.0</version>
        <scope>system</scope>
        <systemPath>d:/myjar.jar</systemPath>
    </dependency>
</dependencies>
  • dependency:指定了单个依赖项的坐标

    • groupIdartifactIdversion:指定了依赖的坐标
    • type:对应 packaging 的类型,如果不使用 type 标签,maven 默认为 jar。
    • scope:指定了依赖的使用范围,以及依赖的传递性,共有5种可用的限定范围
      • compile:如果没有指定 scope 标签,maven 默认为这个范围。编译依赖关系在所有 classpath 中都可用。此外,这些依赖关系被传播到依赖项目。
      • provided:与 compile 类似,但是表示您希望 jdk 或容器在运行时提供它。它只适用于编译测试 classpath,不可传递。
      • runtime:表示编译不需要依赖关系,而是用于执行。它是在运行时测试 classpath,但不是编译 classpath。
      • test:此范围表示正常使用应用程序不需要依赖关系,仅适用于测试编译和执行阶段。它不是传递的。
      • system:此范围与 provided 类似,除了您必须提供明确包含它的 jar。该artifact 始终可用,并且不是在仓库中查找。
    • systemPath:仅当scopesystem才使用。否则,如果设置此元素,构建将失败。该路径必须是绝对路径,因此建议使用 propertie 来指定特定的路径。maven 将不会检查项目的仓库,而是检查库文件是否存在。如果没有,maven 将会失败。
    • optional:设置此依赖项为可选,如果子项目存在该依赖项,则不会传递该依赖给子项目,避免了依赖冲突
    • exclusions:指定一个或多个排除需要排除的传递而来的依赖,每个排除依赖都包含 groupIdartifactId

parent
#

maven 支持继承功能。子 POM 可以使用 parent 指定父 POM ,然后继承其配置。

<parent>
    <groupId>top.ygang</groupId>
    <artifactId>my-parent</artifactId>
    <version>2.0</version>
    <relativePath>../my-parent</relativePath>
</parent>
  • relativePath:在搜索本地和远程存储库之前,它不是必需的,但可以用作 maven 的指示符,优先搜索给定该项目父级的路径。

dependencyManagement
#

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-embedder</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>
</dependencyManagement>

表示依赖 jar 包的声明。即你在项目中的 dependencyManagement 下声明了依赖,maven 不会加载该依赖,dependencyManagement 声明可以被子 POM 继承。

常见的使用方式为,父项目声明<packaging>pom</packaging>,并且使用dependencyManagement来指定依赖以及版本;子项目只需要使用groupIdartifactId来指定依赖,而依赖版本会继承父项目指定的版本。

dependencyManagement 主要是为了统一管理依赖包的版本,确保所有子项目使用的版本一致,类似的还有pluginspluginManagement

dependencyManagement中可以写一个特殊的scope<scope>import</scope>,作用是如果当前的<parent>继承一个不够,那么可以使用这个标签在dependencyManagement继承多个。

properties
#

属性列表。定义的属性可以在pom.xml文件中任意处使用。使用方式为 ${propertie}

<!-- 常用属性 -->
<properties>
    <!-- 指定maven构建项目时使用的编码,防止乱码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 编译代码使用的jdk版本 -->
    <maven.compiler.source>8</maven.compiler.source>
    <!-- 运行代码使用的jdk版本 -->
    <maven.compiler.target>8</maven.compiler.target>
</properties>
  • 内置属性

    • ${project.build.sourceDirectory}:项目的主源码目录,默认为 src/main/java

    • ${project.build.testSourceDirectory}:项目的测试源码目录,默认为 src/test/java

    • ${project.build.directory}:项目构件输出目录,默认为 target/

    • ${project.outputDirectory}:项目主代码编译输出目录,默认为 target/classes/

    • ${project.testOutputDirectory}:项目测试代码编译输出目录,默认为 target/test-classes/

    • ${project.groupId}:项目的 groupId

    • ${project.artifactId}:项目的 artifactId

    • ${project.version}:项目的 version,与${version}等价

    • ${project.build.fianlName}:项目打包输出文件的名称。默认为${project.artifactId}-${project.version}

    • ${project.basedir}pom.xml所在的目录,与${basedir}等价

项目信息配置
#

项目信息相关的这部分标签都不是必要的,也就是说完全可以不填写。

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!--项目名-->
    <name>maven-demo</name>

    <!--项目描述-->
    <description>maven示例</description>

    <!--项目url-->
    <url>https://github.com/gradyyoung/maven-demo</url>

    <!--项目开发年份-->
    <inceptionYear>2019</inceptionYear>

    <!--开源协议-->
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
            <comments>A business-friendly OSS license</comments>
        </license>
    </licenses>

    <!--组织信息(如公司、开源组织等)-->
    <organization>
        <name>...</name>
        <url>...</url>
    </organization>

    <!--开发者列表-->
    <developers>
        <developer>
            <id>1</id>
            <name>ygang1</name>
            <email>example@email.com</email>
            <url>https://www.ygang.top/</url>
            <organization>...</organization>
            <organizationUrl>...</organizationUrl>
            <roles>
                <role>architect</role>
                <role>developer</role>
            </roles>
            <timezone>+8</timezone>
            <properties>...</properties>
        </developer>
    </developers>

    <!--代码贡献者列表-->
    <contributors>
        <contributor>
            <id>1</id>
            <name>ygang2</name>
            <email>example@email.com</email>
            <url>https://www.ygang.top/</url>
            <organization>...</organization>
            <organizationUrl>...</organizationUrl>
            <roles>
                <role>architect</role>
                <role>developer</role>
            </roles>
            <timezone>+8</timezone>
            <properties>...</properties>
        </contributor>
    </contributors>
</project>

环境配置
#

issueManagement
#

这定义了所使用的缺陷跟踪系统(Bugzilla,TestTrack,ClearQuest 等)。虽然没有什么可以阻止插件使用这些信息的东西,但它主要用于生成项目文档。

<issueManagement>
    <system>Bugzilla</system>
    <url>http://127.0.0.1/bugzilla/</url>
</issueManagement>

ciManagement
#

CI 构建系统配置,主要是指定通知机制以及被通知的邮箱。

<ciManagement>
    <system>continuum</system>
    <url>http://127.0.0.1:8080/continuum</url>
    <notifiers>
        <notifier>
        <type>mail</type>
            <sendOnError>true</sendOnError>
            <sendOnFailure>true</sendOnFailure>
            <sendOnSuccess>false</sendOnSuccess>
            <sendOnWarning>false</sendOnWarning>
            <configuration><address>continuum@127.0.0.1</address>
            </configuration>
        </notifier>
    </notifiers>
</ciManagement>

repositories
#

repositories 是遵循 Maven 存储库目录布局的 artifacts 集合。默认的 Maven 中央存储库位于https://repo.maven.apache.org/maven2/上。

<repositories>
    <repository>
        <releases>
            <enabled>false</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>warn</checksumPolicy>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
        </snapshots>
        <id>codehausSnapshots</id>
        <name>Codehaus Snapshots</name>
        <url>http://snapshots.maven.codehaus.org/maven2</url>
        <layout>default</layout>
    </repository>
</repositories>

pluginRepositories
#

repositories 差不多。

profiles
#

settings.xml中的profiles作用一样,但是子标签除了idactivationrepositoriespluginRepositories properties这几个基本的以外,还有类似于dependenciesbuildpom.xml标签,可以更加全面的分类配置项目。

<profiles>
    <profile>
        <id>p1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.31</version>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>p2</id>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.46</version>
            </dependency>
        </dependencies>
    </profile>
</profiles>
激活profile的方式
#
  • 方式一:通过默认<activeByDefault>true</activeByDefault>激活,优先级最低,一旦使用方式二三,则此方式失效
  • 方式二:通过mvn [command] -P profileId激活,例如mvn package -P p2
  • 方式三:通过activation标签中的各种条件激活

构建配置
#

build
#

项目的构建配置

<build>
    <defaultGoal>install</defaultGoal>
    <directory>${basedir}/target</directory>
    <finalName>${artifactId}-${version}</finalName>
    <resources>
        <resource>
            <targetPath>META-INF/plexus</targetPath>
            <filtering>false</filtering>
            <directory>${basedir}/src/main/plexus</directory>
            <includes>
            	<include>configuration.xml</include>
            </includes>
            <excludes>
            	<exclude>**/*.properties</exclude>
            </excludes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.6</version>
            <extensions>false</extensions>
            <inherited>true</inherited>
            <configuration>
            	<classifier>test</classifier>
            </configuration>
            <dependencies>...</dependencies>
            <executions>...</executions>
        </plugin>
    </plugins>
</build>
  • defaultGoal:执行构建时默认的goal或phase,如jar:jar或者package
  • directory:构建的结果所在的路径,默认为${basedir}/target目录
  • finalName:构建的最终结果的名字,默认为${artifactId}-${version},该名字可能在其他plugin中被改变
  • resources:资源的配置。资源文件通常不是代码,不需要编译,而是在项目需要捆绑使用的内容。
    • targetPath: 指定从构建中放置资源集的目录结构。目标路径默认为基本目录。将要包装在jar中的资源的通常指定的目标路径是META-INF
    • filtering:构建过程中是否对资源进行过滤,默认false
    • directory:资源文件的路径,默认位于${basedir}/src/main/resources/目录下
    • includes:一组文件名的匹配模式,被匹配的资源文件将被构建过程处理
    • excludes:一组文件名的匹配模式,被匹配的资源文件将被构建过程忽略。同时被includesexcludes匹配的资源文件,将被忽略。
  • plugins:构建过程中所用到的插件
    • groupIdartifactIdversion :和基本配置中的 groupIdartifactIdversion 意义相同。
    • extensions:是否加载该插件的扩展,默认false
    • inherited:该插件的configuration中的配置是否可以被继承,默认true
    • configuration:该插件所需要的特殊配置,在父子项目之间可以覆盖或合并
    • dependencies:插件本身所需要的依赖
    • executions:该插件的某个goal(一个插件中可能包含多个goal)的执行方式。
      • id:唯一标识
      • goals:要执行的插件的goal(可以有多个),如<goal>run</goal>
      • phase:插件的goal要嵌入到Maven的phase中执行,如verify
      • inherited:该execution是否可被子项目继承
      • configuration:该execution的其他配置参数

reporting
#

包含特定针对 site 生成阶段的元素。某些 maven 插件可以生成 reporting 元素下配置的报告,例如:生成 javadoc 报告。reportingbuild 元素配置插件的能力相似。明显的区别在于:在执行块中插件目标的控制不是细粒度的,报表通过配置 reportSet 元素来精细控制。而微妙的区别在于 reporting 元素下的 configuration 元素可以用作 build 下的 configuration ,尽管相反的情况并非如此( build 下的 configuration 不影响 reporting 元素下的 configuration )。

另一个区别就是 plugin 下的 outputDirectory 元素。在报告的情况下,默认输出目录为 ${basedir}/target/site

<reporting>
    <plugins>
        <plugin>
            ...
            <reportSets>
            <reportSet>
            <id>sunlink</id>
            <reports>
                <report>javadoc</report>
            </reports>
            <inherited>true</inherited>
            <configuration>
                <links>
                    <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
                </links>
            </configuration>
            </reportSet>
            </reportSets>
        </plugin>
    </plugins>
</reporting>
Maven - 点击查看当前系列文章
§ 3、pom.xml 「 当前文章 」