maven知識總結

maven知識總結

1、repository

也就是我們說的倉庫,分為本地倉庫和遠程倉庫。

本地倉庫這個想必大家都知道這個就不說了。

遠程倉庫是什麼呢?

所謂遠程倉庫,就是我們本地倉庫沒有對應的jar(maven從倉庫中下載的不單單是jar,還有其他如pom等等其他文件,這裡就簡單用jar表示maven下載的所有文件)時,maven就會從遠程倉庫去下載,並存儲到本地倉庫中。

下面我們具體看下是怎麼配置的。

<repository>
  <id>spring</id>
  <url>//maven.aliyun.com/repository/spring</url>
  <releases>
    <enabled>true</enabled>
  </releases>
  <snapshots>
    <enabled>true</enabled>
  </snapshots>
</repository>

上面的是阿里雲倉庫中的一個repository配置。具體位置在//developer.aliyun.com/mvn/guide

具體在settings.xml中配置如下圖。

repository不僅可以配置到settings.xml中,也可以配置到maven工程的pom.xml


2、mirror

也就是我們說的鏡像,在//developer.aliyun.com/mvn/guide也能看到有個mirror配置。

<mirror>
  <id>aliyunmaven</id>
  <mirrorOf>*</mirrorOf>
  <name>阿里雲公共倉庫</name>
  <url>//maven.aliyun.com/repository/public</url>
</mirror>

我們需要的文件maven也會從這個mirror中去下載。

既然mirrorrepository都可以下載jar,那它們的區別是什麼呢。

一般來說,maven在本地倉庫找不到jar時,就會通過repository指定的地址去遠端下載。

但是當我們配置了mirror後,如果mirrorOf中的內容和repository中的id匹配,這時,就不會從repository指定的url下載。會從mirror指定的url去下載。

具體mirrorOf的匹配規則有下面幾種。

  • *匹配所有 repo id。
  • external:* 匹配所有存儲庫,除了那些使用 localhost 或基於文件的存儲庫。 當您要排除為集成測試定義的重定向存儲庫時使用此選項。
  • 從 Maven 3.8.0 開始,external:http:* 匹配所有使用 HTTP 的存儲庫,但使用 localhost 的存儲庫除外。
  • 使用逗號作為分隔符指定多個存儲庫
  • 感嘆號可以與上述通配符之一結合使用以排除存儲庫 ID。

下面看個例子:

<mirror>
  <id>aliyunmaven</id>
  <mirrorOf>*,!repo1</mirrorOf>
  <name>阿里雲公共倉庫</name>
  <url>//maven.aliyun.com/repository/public</url>
</mirror>

上面的<mirrorOf>*,!repo1</mirrorOf>就表示除了idrepo1的倉庫外,其他都會從//maven.aliyun.com/repository/public這個路徑中去下載。

換句話說也就是所有的jar包只會在mirror指定的urlidrepo1的倉庫指定的url中去下載。


下面我們具體看個例子。

1.先看下settings.xml的設置。

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

<settings xmlns="//maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="//maven.apache.org/SETTINGS/1.2.0 //maven.apache.org/xsd/settings-1.2.0.xsd">
<localRepository>/Users/xxx/Documents/software/repo</localRepository>
 <mirrors>
   <mirror>
      <id>aliyunmaven</id>
      <mirrorOf>!jcenter,*</mirrorOf>
      <name>阿里雲公共倉庫</name>
      <url>//maven.aliyun.com/repository/public</url>
    </mirror>
  </mirrors>
  
  <profiles>
      <profile>
      <id>jdk</id>
      <repositories>
          <repository>
              <id>jcenter</id>
              <url>//maven.aliyun.com/repository/jcenter</url>
              <releases>
                <enabled>true</enabled>
              </releases>
              <snapshots>
                <enabled>true</enabled>
              </snapshots>
          </repository>
      </repositories>
  </profile>
</profiles>
  
  <activeProfiles>
    <activeProfile>jdk</activeProfile>
  </activeProfiles>
</settings>

settings.xml中“mirrorOf設置的是!jcenter,*,表示所有jar都會從倉庫idjcenter設置的url中和mirror設置的url`中查找。


下面我再新建個maven工程。

這是pom.xml的內容。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0"
         xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mavendemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.28</version>
        </dependency>
    </dependencies>
</project>

我們在maven工程目錄下,執行mvn package打包命令,就會發現jar包優先會從倉庫idjcenter設置的url下載。


如果我們把上面的settings.xmlmirrorOf標籤內容順序做個調整,改成<mirrorOf>*,!jcenter</mirrorOf>。從本地倉庫中刪除剛才下載的jar,重新執行mvn package,就會發現優先從mirror中指定的url中去下載。

再比如,我把pom.xml中需要下載的jar修改為一個不存在的jar,可以看到maven會按照mirrorOf中指定的順序依次去查找,如果全都找不到,就會提示失敗。

    <dependencies>
        <dependency>
            <groupId>org.mytest</groupId>
            <artifactId>mytestmvn</artifactId>
            <version>1.28</version>
        </dependency>
    </dependencies>

我把我本地pom.xml中依賴的jar改成了上面這樣,再去重新執行mvn package.

從上面紅框處就能確認下載順序是和我們mirrorOf指定的順序是一致的。

從上面也能發現當我們配置了多個倉庫時,maven是如何知道jar存在於哪個倉庫的。就是簡單粗暴的按照配置的先後順序依次嘗試去下載。

3、profile

我們可以通過設置多個profile標籤來定義各種不同的配置。

可以通過activeProfile標籤來激活配置。也可以在profile標籤內通過activeByDefault標籤設置配置默認是否激活,同時也可以設置條件,具體就不展開了。這部分內容可以查看官方文檔profile章節

4、dependencyManagement

當我們一個項目的模塊比較多時,為了避免不同模塊引入jar版本混亂的問題,這時就需要通過dependencyManagement來解決。

這時我們就可以在項目頂級pom中使用dependencyManagement標籤定義好所有子模塊依賴的jar的版本。這樣子模塊需要對應的jar時,就不需要指定版本號。避免了不同子模塊引入同一個jar不同版本的問題。同時如果jar的版本升級,直接在頂級pom中修改版本號就可以了,子模塊根本不需要感知版本號的修改。

dependencyManagement標籤內定義的只是管理依賴,並不會將裏面的定義的jar作為工程依賴。

下面我們看個例子。

首先我們定義一個maven工程(工程名mavendemo),再定一個子模塊(工程名childdemo)。

父工程mavendemopom.xml

子工程childdemopom.xml

5、Importing Dependencies

通過上面都知道maven工程可以通過父子關係來管理依賴。但是由於maven工程只能單繼承。不能讓一個maven工程同時依賴兩個不同的父工程。這時就可以使用.Importing Dependencies來完成。

更多內容,查看官方文檔

Tags: