Maven必知必会 - settings文件解析

1,611 阅读5分钟

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

Maven必知必会 - settings文件解析

刚入职一个新公司的时候,很多时候我们需要和老员工要这么个settings文件。本文就介绍下settings的这些配置项及其作用。如果自己整理公司环境的时候出了什么问题,可以查阅并进行分析排查下。

Maven的配置文件是有2个等级的:

  1. 用户级别的Maven配置settings.xml
    • 一般放在 ${user.home}/.m2/settings.xml目录下
    • -s /path/to/user/settings.xml 覆盖默认的settings文件
  2. 全局级别的Maven配置settings.xml
    • 一般放在${maven.conf}/settings.xml目录下
    • -gs /path/to/global/settings.xml 可以指定覆盖默认的settings文件配置

localRepository

 <localRepository>/xxx/env/maven/repo</localRepository>

本地仓库路径的配置

  • 默认:${user.home}/.m2/repository
  • 指定:<localRepository>/path/to/local/repo</localRepository>

interactiveMode

<interactiveMode>true</interactiveMode>

interactiveMode 交互模式,表示是否需要和用户输入进行交互,如果设置为false maven会尝试用默认值替代。(即执行maven命令的时候,是否要走和用户交互的流程)

比如命令行创建项目的时候,我们需要指定项目的GAV,这些是maven无法用默认值替代,所以会直接失败。

默认:true

offline

<offline>false</offline>

offline Maven是否需要在离线模式下运行,如果不希望链接远程的仓库就将其设置为true,那就不会去远程仓库拉去jar,一般不会用这个配置。

默认:false

pluginGroups

  <pluginGroups>
    <!-- pluginGroup
    指定自己插件的groupId
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
  </pluginGroups>

pluginGroups 插件的groupIds候选

  • 我们使用plugin的时候,如果没有显示指定plugin的groupId的时候,maven会从配置的groupId里面去找插件
  • maven默认会添加"org.apache.maven.plugins" and "org.codehaus.mojo"这2个groupId

proxies

  <proxies>
    <!-- proxy
    <proxy>
      <id>optional</id>  id是可选的,这个id和profile的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>

proxies 代理,可能一些公司防火墙等安全问题,需要配置代理访问远程仓库。默认会使用列表中第一个代理配置,除非特殊指定(系统配置属性或者命令行指定切换)。

servers

  <servers>
    <server>
      <id>deploymentRepo</id> 
      <username>repouser</username>
      <password>repopwd</password>
    </server>
  </servers>

主要是用于连接私服的时候一些认证需要的信息。(id的属性必须全局唯一),可以配置2种:

   1. 账号密码(大部分都是配置了账号密码)
   2. privateKey

我们一般都是上传jar包的时候,需要一些认证信息,这时候就需要指定对应仓库的server认证信息。为了安全,仓库信息可以直接配置POM文件中,认证信息必须配置在settings.xml文件中

该id与distributionManagement中repository元素的id一定要相匹配!因为需要通过这个id来获取认证信息才能上传jar。最并且好让该id和repository/mirror中的id对应的,他们代表了同一套。

mirrors

  <mirrors>
    <mirror>
      <id>alimaven</id>
      <!--指定一个镜像的地址,而不是仓库的地址。ID必须唯一 -->
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>*</mirrorOf>
  </mirrors>

配置镜像,一个镜像一般都对应一个远程仓库,通过mirrorOf配置指定对应仓库的id。比如上面就是指定的central,即表示该镜像为Maven中央仓库的镜像。

那么在Maven需要从远程仓库拉取jar包的时候,会通过repository的id去mirrors找是否mirrorOf为该id的配置,如果有就会拦截请求转发请求镜像库。否则还是使用repository的配置。

一个pom指定的jar包,如果每次都实时到一个仓库去拉取的话,网络传输压力就很大,所以人们在多个地方建立了镜像库分散压力。

一般都因为被镜像的服务器的id,我们远程仓库访问比较慢,于是可以设置一个镜像服务,这里mirrorOf就是指定该镜像是属于哪个远程仓库的镜像。比如:我们maven中央仓库的默认id是central,我们设置了一个该仓库的镜像,就要指定为central。每个server配置都有一个唯一的id属性,这个镜像是id相同的repository再拉取额外jar包的时候的首选。

比如:我们一般都对maven的中央仓库的地址设置阿里云的镜像库地址来加速访问。

重点配置

mirror中一个比较重要的属性mirrorOf

mirrorOf:这个配置可以多种形式:

  1. 我们指定了repository的id的话,那么就是说拉取这个repository的jar的时候,会通过该镜像去拉取。(支持配置多个repo)
  2. 我们还可以配置 *, 那么就代表所有的远程服务将被该镜像给代理!那么所有远程服务的拉取jar请求都将转发给该镜像!这可能就会导致我们配置了私服但不能使用。
  3. 配置external:*:表示匹配本地部署的远程仓库外(localhost开头,或者file://协议开头的仓库配置)的所有远程仓库。
  4. 配置*,!repo1,匹配除了repo1之外的所有远程仓库。即repo1还是用自己的repo地址,而其他的走该镜像。

总结

单个mirror配置

  • repository 没有对应的<mirrorOf>指定,将从repository配置地址拉取
  • <mirrorOf>指定了repository的id的,优先是使用mirror的地址。
  • <mirrorOf>指定了*,会代理所有的仓库,即所有的仓库都会用mirror的地址。

多个mirror配置

  • 多个配置的<mirrorOf> 指定相同的id,那么只会使用第一个mirror

profiles

  <profiles>
    <!--这是是通过jdk前缀来匹配的配置-->
    <profile>
      <id>jdk-1.4</id>
      <activation>
        <jdk>1.4</jdk>
      </activation>
      <repositories>
        <repository>
          <id>jdk14</id>
          <name>Repository for JDK 1.4 builds</name>
          <url>http://www.myhost.com/maven/jdk14</url>
          <layout>default</layout>
          <snapshotPolicy>always</snapshotPolicy>
        </repository>
      </repositories>
    </profile>
    <!--通过环境来指定的配置-->
    <profile>
      <id>env-dev</id>
      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>
      <!--通可以在这里设置一些属性 -->
      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
	<!-- 一般配置 -->
    <profile>
      <id>central</id>
      <repositories>
        <repository>
          <id>central</id>
          <name>local private nexus</name>
          <url>http://xxxx/repositories/public</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>local private nexus</name>
          <url>http://xxxx/public</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>

配置不同环境的配置信息,主要存放不同环境下的一些对应的配置。我们一般通过这个来隔离测试/生产环境的,不同的环境使用不同的配置,特别是用来配置repository各个环境私服信息。

可以通过多种方式来激活对应的配置:

  1. 下面activeProfiles标签配置指定环境
  2. 系统配置属性指定
  3. jdk版本前缀匹配,比如JDK版本在1.4.2_07下,可以激活1.4
  4. 可以命令行参数进行指定

activeProfiles

  <activeProfiles>
    <activeProfile>alwaysActiveProfile</activeProfile>
    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
  </activeProfiles>

设置需要默认激活的profile,如果指定的profile有对应配置则激活,无则忽略,不影响执行。指定了多个,会依次去这些profile去找那些找不到的jar包。

这个profile可以我们POM文件中配置的profile也是类似于全局和当前项目的关系。