您现在的位置是:首页 >技术教程 >Maven 超级pom、最终有效pom、pom 详解、settings 详解网站首页技术教程

Maven 超级pom、最终有效pom、pom 详解、settings 详解

ares5k 2024-10-25 12:01:04
简介Maven 超级pom、最终有效pom、pom 详解、settings 详解

超级pom

在项目的 pom.xml 中不进行任何配置,仍然不影响 Maven 构建的运行,是因为所有的 pom 文件都会继承一个默认的配置,这个配置称为 超级pom,在自己项目中的配置会覆盖 超级pom 中的配置,未被覆盖的就会继续使用 超级pom 中的配置

超级pom 定义在 maven-model-builder.jar 中,如果想查看其定义,需要将 jar 包解压,解压后 超级pom 的完整路径为: maven 安装目录libmaven-model-builder-3.6.3.jarorgapachemavenmodelpom-4.0.0.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!-- START SNIPPET: superpom -->
<project>
  <modelVersion>4.0.0</modelVersion>

  <repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

  <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

  <build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    <pluginManagement>
      <!-- NOTE: These plugins will be removed from future versions of the super POM -->
      <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
  </reporting>

  <profiles>
    <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    <profile>
      <id>release-profile</id>

      <activation>
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>

      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <goals>
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-javadoc-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-javadocs</id>
                <goals>
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
              <updateReleaseInfo>true</updateReleaseInfo>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>
<!-- END SNIPPET: superpom -->

最终有效pom

真实的项目中,想一眼看懂当前 Maven 工程都使用了什么配置是很困难的,因为一个 Maven 工程最终的 Pom 配置会受到:父工程 pom,当前工程 pom,超级pom,默认生命周期插件、甚至 setttings.xml 文件中 profiles 的影响

最终有效pom:上述会影响 pom 的因素合并后,所形成的可以被 Maven 构建时真正使用的最终配置

能够影响 pom 的因素这么多,如果我们手动挨个比较来确定最终有效的pom 肯定是不可取的,太离谱,我们可以借助 Maven 插件来自动计算,在有 pom.xml 的路径下使用 maven-help-plugin 插件的 effective-pom 目标就可以

演示

项目的 pom.xml 中,除了 groupId、artifactId、version 之外,没有其他任何配置,运行 mvn help:effective-pom 后效果如下(从结果来分析,最终有效pom的结构为:超级pom的配置 + 默认生命周期插件的配置,这也正可以解释,为何超级pom 中没有默认生命周期插件的配置,而 Maven 却能运行构建功能,因为在最终的有效Pom中,生命周期插件的配置已经被添加):

Effective POMs, after inheritance, interpolation, and profiles are applied:

<?xml version="1.0" encoding="GBK"?>
<!-- ====================================================================== -->
<!--                                                                        -->
<!-- Generated by Maven Help Plugin                                         -->
<!-- See: https://maven.apache.org/plugins/maven-help-plugin/               -->
<!--                                                                        -->
<!-- ====================================================================== -->
<!-- ====================================================================== -->
<!--                                                                        -->
<!-- Effective POM for project 'com.ares5k:ares5k-pom:jar:1.0-SNAPSHOT'     -->
<!--                                                                        -->
<!-- ====================================================================== -->
<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">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ares5k</groupId>
  <artifactId>ares5k-pom</artifactId>
  <version>1.0-SNAPSHOT</version>
  <repositories>
    <repository>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
    </pluginRepository>
  </pluginRepositories>
  <build>
    <sourceDirectory>G:ares5k-pomsrcmainjava</sourceDirectory>
    <scriptSourceDirectory>G:ares5k-pomsrcmainscripts</scriptSourceDirectory>
    <testSourceDirectory>G:ares5k-pomsrc	estjava</testSourceDirectory>
    <outputDirectory>G:ares5k-pom	argetclasses</outputDirectory>
    <testOutputDirectory>G:ares5k-pom	arget	est-classes</testOutputDirectory>
    <resources>
      <resource>
        <directory>G:ares5k-pomsrcmain
esources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>G:ares5k-pomsrc	est
esources</directory>
      </testResource>
    </testResources>
    <directory>G:ares5k-pom	arget</directory>
    <finalName>ares5k-pom-1.0-SNAPSHOT</finalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-clean-plugin</artifactId>
        <version>2.5</version>
        <executions>
          <execution>
            <id>default-clean</id>
            <phase>clean</phase>
            <goals>
              <goal>clean</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.6</version>
        <executions>
          <execution>
            <id>default-testResources</id>
            <phase>process-test-resources</phase>
            <goals>
              <goal>testResources</goal>
            </goals>
          </execution>
          <execution>
            <id>default-resources</id>
            <phase>process-resources</phase>
            <goals>
              <goal>resources</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <executions>
          <execution>
            <id>default-jar</id>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <executions>
          <execution>
            <id>default-compile</id>
            <phase>compile</phase>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
          <execution>
            <id>default-testCompile</id>
            <phase>test-compile</phase>
            <goals>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12.4</version>
        <executions>
          <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
              <goal>test</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.4</version>
        <executions>
          <execution>
            <id>default-install</id>
            <phase>install</phase>
            <goals>
              <goal>install</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-deploy-plugin</artifactId>
        <version>2.7</version>
        <executions>
          <execution>
            <id>default-deploy</id>
            <phase>deploy</phase>
            <goals>
              <goal>deploy</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-site-plugin</artifactId>
        <version>3.3</version>
        <executions>
          <execution>
            <id>default-site</id>
            <phase>site</phase>
            <goals>
              <goal>site</goal>
            </goals>
            <configuration>
              <outputDirectory>G:ares5k-pom	argetsite</outputDirectory>
              <reportPlugins>
                <reportPlugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-project-info-reports-plugin</artifactId>
                </reportPlugin>
              </reportPlugins>
            </configuration>
          </execution>
          <execution>
            <id>default-deploy</id>
            <phase>site-deploy</phase>
            <goals>
              <goal>deploy</goal>
            </goals>
            <configuration>
              <outputDirectory>G:ares5k-pom	argetsite</outputDirectory>
              <reportPlugins>
                <reportPlugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-project-info-reports-plugin</artifactId>
                </reportPlugin>
              </reportPlugins>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <outputDirectory>G:ares5k-pom	argetsite</outputDirectory>
          <reportPlugins>
            <reportPlugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-project-info-reports-plugin</artifactId>
            </reportPlugin>
          </reportPlugins>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <reporting>
    <outputDirectory>G:ares5k-pom	argetsite</outputDirectory>
  </reporting>
</project>

pom 详解


工程坐标 gav

没啥好说的,就是声明当前工程的坐标,用来在 Maven 中进行唯一定位的,简称 gav

<groupId>com.ares5k</groupId>
<artifactId>ares5k-pom</artifactId>
<version>1.0-SNAPSHOT</version>

打包方式 packaging

Maven 在执行生命周期 package 阶段时,会根据打包方式,在最终有效pom 里添加合适的默认插件,Maven 的打包方式有很多,列举几个我常用的:

  • war:项目最终需要放到外置 servlet web 容器运行的场景适合使用,Maven 会将 maven-war-plugin 插件添加到最终有效pom 中当作 package 阶段的默认生命周期插件,执行 package 阶段的构建后会生成一个 war 文件

  • jar:想通过 java -jar 直接运行项目的场景适合使用,会将 maven-jar-plugin 插件添加到最终有效pom中当作 package 阶段的默认生命周期插件,执行 package 阶段的构建后会生成一个 jar 文件

  • pom:作为父工程或聚合工程的场景适合使用,主要目的是定义工程结构,执行后,不会生成 jar 或 war 文件

  • maven-plugin:自定义生命周期插件的场景适合使用,Maven 会将 maven-jar-pluginmaven-plugin-plugin 插件添加到最终有效pom 中当作 package 阶段的默认生命周期插件,执行 package 阶段的构建后会生成一个 jar 文件

<packaging>jar</packaging>

指定父工程 parent

子模块中使用,不写 <relativePath> 时会从本地或远程仓库中通过 GAV 来定位父工程,写 <relativePath> 时会先从 <relativePath> 中指定的相对路径中寻找父工程,找不到再从本地或远程仓库查找

  <parent>
    <groupId>com.ares5k</groupId>
    <artifactId>ares5k-pom-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../ares5k-pom-parent</relativePath>
  </parent>

聚合子模块 modules

聚合工程中使用,将子模块声明在 <module> 后,在聚合工程中执行 Maven 生命周期命令时,所有子模块的相同生命周期命令也都会被执行,有两点要注意:

  1. 不要忘了在聚合工程中指定 <packaging>pom</packaging>
  2. <module> 中的值是子模块工程的相对路径,而不是子模块的 <artifactId>
<modules>
  <!-- 子模块不在聚合工程目录中 -->
  <module>../ares5k-module-test</module>
  <!-- 子模块在聚合工程目录中 -->
  <module>ares5k-module-inner</module>
</modules>

定义远程仓库 repositories

定义下载依赖时的远程仓库,Maven 默认有一个中央仓库 <id>central</id>,我们也可以自己添加新的远程仓库,当定义多个远程仓库后,下载依赖时会按照仓库的定义顺序依次去查找下载,直到找到依赖为止,如果所有自定义仓库都未找到所需依赖,那么最后会去 Maven 默认的中央仓库查找

下面是 Maven 默认中央仓库的定义,我们可以仿照这个结构,添加自己的 <repository>,远程仓库内部又会分为发布库和快照库,下面代码中 <snapshots><releases> 就用来指定是去发布库下载还是快照库下载

<repositories>
  <repository>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <releases>
      <enabled>true</enabled>
    </releases>
    <id>central</id>
    <name>Central Repository</name>
    <url>https://repo.maven.apache.org/maven2</url>
  </repository>
</repositories>

定义远程插件仓库 pluginRepositories

Maven 下载插件类型依赖时的远程仓库,也就是在 <plugin> 中声明的依赖。用法和前面的 <repositories> 大同小异,其默认的插件远程仓库结构如下,想使用自己的插件远程仓库时,添加 <pluginRepository> 即可:

<pluginRepositories>
  <pluginRepository>
    <releases>
      <enabled>true</enabled>
    </releases>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
    <id>central</id>
    <name>Central Repository</name>
    <url>https://repo.maven.apache.org/maven2</url>
  </pluginRepository>
</pluginRepositories>

工程中引入依赖 dependencies

定义在 <dependencies> 中的依赖会被下载到本地仓库并被工程引用,想添加新的依赖就追加 <dependency> 节点,然后在节点中指定待引入依赖的工程坐标,既 gav

<dependencies>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
  </dependency>
</dependencies>

依赖版本管理 dependencyManagement

常在父工程和子模块搭配时使用,在父工程的 <dependencyManagement> 中定义版本,在子模块的 <dependency> 真正引用。在同一工程中也可以同时使用 <dependencyManagement><dependency>,但是没有意义

上面说的 <dependency> 的节点路径是: project->dependencies->dependency,而不是 project->dependencyManagement->dependencies->dependency

<dependencyManagement> 声明依赖后,其不会触发下载和引用,只有在 project->dependencies->dependency 中真正引用后,才会触发下载和引用,并且此时可以省略版本信息 <version>

<!-- 定义版本 -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <!-- 引入,不需要指定 version  -->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
</dependencies>

指定远程部署库 distributionManagement

一般搭建私服时常用,执行 Maven 生命周期 deploy 阶段后,会将 package 阶段打好的包,发送到私服

私服就是自己搭建的远程仓库,一般用 nexus 做私服的比较多,远程仓库中又细分发布库和快照库,分别与 <repository> <snapshotRepository> 对应

<distributionManagement>
  <repository>
    <id>ares5k-release</id>
    <url>http://xxx.xxx.xxx.xxx:xxxx/repository/release/</url>
  </repository>
  <snapshotRepository>
    <id>ares5k-snapshot</id>
    <url>http://xxx.xxx.xxx.xxx:xxxx/repository/snapshot/</url>
  </snapshotRepository>
</distributionManagement>

构建 build

<build> 节点内,主要是项目构建相关的配置,大部分场合就是引入和配置一些生命周期插件

设置项目基础构建信息

主要是针对源代码路径、资源文件路径、编译后输出路径、打包后路径、打包名称等进行设置,这些都是 Maven 默认生命周期插件执行时所需要的信息

节点名描述
sourceDirectoryJava 源代码路径
testSourceDirectory测试用的 Java 源代码路径
outputDirectoryJava 源代码编译后的二进制文件存放路径
testOutputDirectory测试用的 Java 源代码编译后的二进制文件存放路径
resources资源文件路径
testResources测试用的资源文件路径
directory打包后,包的存放路径
finalName打包的包名

示例如下,注意路径中的正反斜杠:

<build>
  <sourceDirectory>G:/ares5k-pom/src/main/java</sourceDirectory>
  <testSourceDirectory>G:/ares5k-pom/src/test/java</testSourceDirectory>
  <outputDirectory>G:/ares5k-pom/target/classes</outputDirectory>
  <testOutputDirectory>G:/ares5k-pom/target/test-classes</testOutputDirectory>
  <resources>
    <resource>
      <directory>G:/ares5k-pom/src/main/resources</directory>
    </resource>
  </resources>
  <testResources>
    <testResource>
      <directory>G:/ares5k-pom/src/test/resources</directory>
    </testResource>
  </testResources>
  <directory>G:/ares5k-pom/target</directory>
  <finalName>ares5k-pom-3-1.0-SNAPSHOT</finalName>
</build>

引入插件 plugins

通过追加 <plugin> 节点来新增插件,<executions> 部分是用来将插件与生命周期进行绑定的,如果是 Maven 的默认生命周期插件还好,如果是自己引入的非 Maven 默认生命周期插件,不设置 <executions> 的话,就无法将插件和生命周期绑定,也就不能通过生命周期构建命令直接运行插件,只能通过运行插件的方式来运行插件,<phase> 用来绑定生命周期阶段,<goal> 用来指定该阶段执行的插件目标

上述部分不太理解的,可以看我关于 maven 自定义插件的文章,相信会有更好的理解

<configuration> 部分是设置插件的属性,每个插件都有自己的属性,所以这个地方无法展开来讲

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>2.3.7.RELEASE</version>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
          <phase>package</phase>
        </execution>
      </executions>
      <configuration>
        <mainClass>com.ares5k.App</mainClass>
      </configuration>
    </plugin>
  </plugins>
</build>

管理插件 pluginManagement

一般定义在父工程中,网上很多文章都说 <pluginManagement><dependencyManagement> 一样,声明插件后不会真正的引入,必须要子模块的 project->plugins->plugin主动声明时才能真正的引入,我不知道他们测没测过,我在 maven 3.6.3 中测试过程是这样的:

  • 在父工程的 pluginManagement 中声明一个插件
  • 子工程的 projecet->plugins->plugin 中不主动引入
  • 在子工程 pom.xml 目录运行构建命令

结果:依然使用了父工程 pluginManagement 中声明的插件,这个结果和网上说的完全不同,反正我自己是相信测试结果,所以 pluginManagement 在我看来并不是与 dependencyManagement 一样用来管理版本,而是统一管理插件

<pluginManagement>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.1.2</version>
    </plugin>
  </plugins>
</pluginManagement>

备用配置 profiles

当项目需要满足多环境配置时,比如开发环境、测试环境、商用环境、甚至是 Java 8 环境 和 Java 17 环境,每个环境的 pom.xml 配置肯定都有不一样的地方,如果准备很多份 pom.xml 文件,然后以文件替换的方式来实现环境切换就很麻烦

上述场景就可以使用备用配置的方式,将各个环境间相同的配置像以前一样写在 pom.xml 中,然后将各环境间不同的地方,定义在 <profiles> 中作为备用配置,当使用 Maven 执行构建时,在命令中指定想应用的备用配置,让其加入最终有效pom中,实现环境切换的效果

<profile> 节点中可以包函 <build><dependencies><repositories><pluginRepositories><properties><dependencyManagement><distributionManagement> 等信息,但是不能包函 gav<parent><packaging> 这种工程信息

来个示例

假设项目有两个运行环境,其要求如下:

  1. 要求 环境 A 和 环境 B 都使用 spring-boot-starter 模块
  2. 环境 A 时,要求引入 spring-boot-maven-plugin 插件来实现打包
  3. 环境 B 时,要求引入 lombok 模块

上面这种情况就是很典型的备用配置适用场景,我们可以这样实现环境切换:

  1. spring-boot-starter 模块是两个环境都需要的,就正常在 pom.xml 中引入就可以
  2. 为 环境 A 和 环境 B 不同的地方,分别定义专属的备用配置,既分别定义 <profile>

配置如下每个 <profile> 都必须要有自己的唯一 <id>

<!-- 环境A 和 环境B 都要求使用 spring-boot -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.4.1</version>
    </dependency>
</dependencies>

<profiles>
    <!-- 环境A的配置 -->
    <profile>
        <id>ares5k-A</id>
        <build>
            <plugins>
                <!-- 引入 spring-boot-maven-plugin -->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>2.3.7.RELEASE</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                            <phase>package</phase>
                        </execution>
                    </executions>
                    <configuration>
                        <mainClass>com.ares5k.App</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>

    <!-- 环境B的配置 -->
    <profile>
        <id>ares5k-B</id>
        <dependencies>
            <!-- 引入 lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.24</version>
            </dependency>
        </dependencies>
    </profile>
</profiles>

现在 pom.xml 已经配置完成,之后构建时通过语法 mvn 生命周期阶段 -P<profile Id> 就可以实现环境切换了

以上面配置为例,用环境A的备用配置打包,命令为 mvn package -Pares5k-A

假设经常使用环境A的配置进行打包,那么每次输入命令都需要指定 <profile Id> 就显得很麻烦,我们也可以在 <profile> 节点下添加激活条件:

<profile>
  <id>ares5k-A</id>
  <!-- 激活条件为默认激活 -->
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <build>
    <plugins>
    .......
</profile>

添加了上面的配置后,环境A 的备用配置就变成了默认激活,以后再想用 环境A 的配置构建项目时,直接输入mvn package 就可以,不需要指定 <profile Id> 了。<activation> 下的激活方式有很多,<activeByDefault> 则是默认激活的意思,其他的激活方式有:

<!-- 是否默认激活 -->
<activeByDefault>false</activeByDefault>

<!-- 当 Java 版本是 1.8 时,自动激活 -->
<jdk>1.8</jdk>

<!-- 当操作系统是 WinXp 32位时,自动激活 -->
<os>
  <name>Windows XP</name>
  <family>Windows</family>
  <arch>x86</arch>
</os>

<!-- 当构建时,传入的属性 ares5k-prop=6666 时,自动激活 -->
<!-- 例如:mvn package -Dares5k-prop=6666 -->
<property>
  <name>ares5k-prop</name>
  <value>6666</value>
</property>

<!-- 当文件存在时自动激活 -->
<file>
  <exists>env.properties</exists>  
</file>

<!-- 当文件不存在时自动激活 -->
<file>
  <missing>env.properties</missing>
</file>

当指定了多个激活条件时,Maven 3.2.2 之前只要满足一个条件,备用配置就会被激活,Maven 3.2.2 开始,必须所有条件都满足,备用配置才会被激活

settings 详解

Maven 核心配置文件位置:Maven 安装目录/conf/settings.xml,这是全局级别的配置文件,如果将其复制到用户目录内(以 Windows 为例, C:Users{用户文件夹}.m2) 中,那么它的级别会变成用户级,当两个文件都存在,用户目录内的优先级更高

这个文件没啥太多说的,因为节点很少,而且原始的文件中,对每一个节点都有详细的注释说明,我这里就对几个常用的聊一聊

设置本地仓库路径 localRepository

Maven 从远程仓库下载依赖后,会将依赖放到本地仓库中,等未来在需要时就直接用本地仓库中的依赖,默认的本地仓库路径在用户目录内(以 Windows 为例 C:Users{用户文件夹}.m2 epository), 可以通过 <localRepository> 修改本地仓库路径,修改后再次下载的依赖会存放在新的路径内,查找本地仓库时也会在新的路径内查找

<!-- localRepository
 | The path to the local repository maven will use to store artifacts.
 |
 | Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>E:maven
epository</localRepository>

查找自定义插件 pluginGroups

想在项目中使用自定义 Maven 插件时使用,<pluginGroup> 中指定自定义插件的 <groupId> 即可

<!-- pluginGroups
 | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
 | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
 | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
 |-->
<pluginGroups>
  <!-- pluginGroup
   | Specifies a further group identifier to use for plugin lookup.
  <pluginGroup>com.your.plugins</pluginGroup>
  -->
  <pluginGroup>com.ares5k</pluginGroup>
</pluginGroups>

设置仓库镜像 mirrors

通过 <mirrorOf> 指定要拦截的远程仓库ID,当 Maven 对远程仓库发起请求时,会将目标地址替换成 <url>

<!-- mirrors
 | This is a list of mirrors to be used in downloading artifacts from remote repositories.
 |
 | It works like this: a POM may declare a repository to use in resolving certain artifacts.
 | However, this repository may have problems with heavy traffic at times, so people have mirrored
 | it to several places.
 |
 | That repository definition will have a unique id, so we can create a mirror reference for that
 | repository, to be used as an alternate download site. The mirror site will be the preferred
 | server for that repository.
 |-->
<mirrors>
  <!-- mirror
   | Specifies a repository mirror site to use instead of a given repository. The repository that
   | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
   | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
   |
  <mirror>
    <id>mirrorId</id>
    <mirrorOf>repositoryId</mirrorOf>
    <name>Human Readable Name for this Mirror.</name>
    <url>http://my.repository.com/repo/path</url>
  </mirror>
  -->
  <mirror>		
    <id>aliyun</id>
    <name>aliyun</name>
    <mirrorOf>central</mirrorOf>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>		
  </mirror>
</mirrors>

设置仓库访问密码

当仓库需要授权访问时,我们必须通过 <servers> 设置访问时的账号密码,否则无法下载或上传模块,server->id 的值不能乱写,必须在下面几个中选择:

  • 与部署库发布库ID相同:节点路径,distributionManagement -> repository -> id
  • 与部署库快照库ID相同:节点路径,distributionManagement -> snapshotRepository-> id
  • 与插件远程仓库ID相同:节点路径,pluginRepositories -> pluginRepository-> id
  • 与远程仓库ID相同:节点路径,repositories -> repository-> id
  • 与镜像仓库ID相同:节点路径,mirrors -> mirror -> id
<servers>
  <!-- server
   | Specifies the authentication information to use when connecting to a particular server, identified by
   | a unique name within the system (referred to by the 'id' attribute below).
   |
   | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
   |       used together.
   |
  <server>
    <id>deploymentRepo</id>
    <username>repouser</username>
    <password>repopwd</password>
  </server>
  -->

  <!-- Another sample, using keys to authenticate.
  <server>
    <id>siteServer</id>
    <privateKey>/path/to/private/key</privateKey>
    <passphrase>optional; leave empty if not used.</passphrase>
  </server>
  -->
  <!-- 为 id=ares5k-nexus 的仓库设置访问密码 -->
  <server>
    <id>ares5k-nexus</id>
    <username>ares5k</username>	
    <password>123456</password>
  </server>
</servers>

<mirrors>
  <!-- 镜像仓库需要授权访问 -->
  <mirror>		
    <id>ares5k-nexus</id>
    <name>aliyun</name>
    <mirrorOf>central</mirrorOf>
    <url>http://xxx.xxx.x.xx:xxxx/ares5k/public</url>		
  </mirror>
</mirrors>

备份配置 profiles

和前面 pom.xml 中的 <profiles> 一样,只不过 settings.xml 中的是全局级别,pom.xml 中的是项目级别

激活备份配置 activeProfiles

在前面讲的 pom.xml 中定义 <profile> 的知识点中,介绍了两种启用备份配置的方式:

  1. 运行构建命令时,通过 -P<profile id> 指定激活的备份配置
  2. <profile> 节点下通过添加 <activation> 节点来激活备份配置

settings.xml 中多了一种方式来激活备份配置,就是利用 <activeProfiles> 节点,在 <activeProfiles> 的子节点<activeProfile> 中指定 <profile.id> 就可以激活对应的备份配置

<!-- 定义备份配置 -->
<profiles>
  <profile>   
    <id>ares5k</id>   
    <properties>   
      <maven.compiler.source>1.8</maven.compiler.source>   
      <maven.compiler.target>1.8</maven.compiler.target>    
    </properties>   
  </profile>
<profiles>

<!-- activeProfiles
 | List of profiles that are active for all builds.
 |
<activeProfiles>
  <activeProfile>alwaysActiveProfile</activeProfile>
  <activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
<!-- 启用备份配置 -->
<activeProfiles>
  <activeProfile>ares5k</activeProfile>
</activeProfiles>

网络代理 proxies

当网络访问不顺畅或无法访问外部网络时,可以设置访问代理服务器,由代理服务器真正发起网络请求

说实话我没用过这个功能,因为我一直用的国内镜像仓库, 网络访问一直顺畅,还没有机会使用这个功能,我把原始配置文件中这部分的注释粘过来了,感觉没啥东西,实际使用时对照注释中的例子简单改改就行

<proxies>
  <!-- proxy
   | Specification for one proxy, to be used in connecting to the network.
   |
  <proxy>
    <id>optional</id>
    <active>true</active>
    <protocol>http</protocol>
    <username>proxyuser</username>
    <password>proxypass</password>
    <host>proxy.host.net</host>
    <port>80</port>
    <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
  </proxy>
  -->
</proxies>
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。