每次换个环境都得搞下仓库,太烦了 | 那是因为你还没搞懂 settings 终极大招

5,479 阅读3分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

远程仓库傻傻分不清

  • 公司内部大多都会存在 maven 私服,个人也会搭建 maven 私服,有的时候项目需要使用第三方提供的私服,随着时间的推移我们的 maven setting.xml 配置文件会配置很多私服地址。这不我现在就被这些地址搞乱了,不知道 mirror 和 repository 之间作用与区别了。

image-20221016133445726.png

超级POM

  • 超级POM是所有pom隐式继承一个父类。他存在于 apache-maven-3.6.3\lib\maven-model-builder-3.6.3.jar中。maven-model-builder-3.6.3.jar\org\apache\maven\model\pom-4.0.0.pom 具体内容如下:
<?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作用

  • 仔细观察下文件内容就可以知道,他存在的意义就是指定默认中央仓库。我们都知道如无特殊配置默认都回去中央仓库寻找我们需要的jar的。

Repository

定义仓库地址

  • 相信很多情况下你都会有自己的私服,所有仓库地址肯定指向私服服务器,这个时候我们只需要在 mavensettings.xml 文件中配置即可覆盖默认仓库地址
<repositories>
    <repository>
        <id>aliyun-repository</id>
        <name>aliyun repository</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </repository>
</repositories>

image-20221016140432306.png

  • 可以清楚看到所有的jar包都去aliyun仓库寻找而不是默认的中央仓库寻找了。

多个repository

  • 说回正文有的时候我们需要整合第三方jar ,但是他们拥有自己的私服,我们就不得不同时配置自己私服和别人私服共同下载jar了。那我们可以在 settings.xml 中配置多个 repository 即可。maven 会按照顺序去仓库里寻找jar ,寻找不到则会轮训下一个仓库。
<repositories>
    <repository>
        <id>aliyun-repository</id>
        <name>aliyun repository</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </repository>
    <repository>
        <id>nexus</id>
        <name>local private nexus</name>
        <url>http://xxx.xxx.xx.xxx:8081/repository/maven-public/</url>
        <releases>
             <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

image-20221016141340366.png

  • 我们能够清楚的发现一次编译会从两个仓库分别请求jar , 这就是因为部分jar 在阿里云没有,maven 自动会去下一个仓库寻找。

Mirror

  • mirror则相当于一个代理,它会拦截去指定的远程repository下载构件的请求,然后从自己这里找出构件回送给客户端。配置mirror的目的一般是出于网速考虑。
  • 和 repository 不同的是即使配置多个 mirror 也不会按顺序加载的,maven 会按照 mirrorOf 匹配到的mirro集合中的 ID 进行排序选取第一个进行拦截替代。仅当第一个无法访问时才会访问第二个。

image-20221016142935173.png

  • 按照镜像匹配规则当我们访问tom1仓库时,下面三个镜像会匹配到,按照顺序 maven 选择第一个进行下载,如果第一个服务可以正常访问那么不管有没有找到jar 都只会在第一个镜像服务查找,不会轮训到其他镜像查找。

本文正在参加「金石计划 . 瓜分6万现金大奖」