天天看點

Maven核心概念詳解

坐标

Maven坐标主要組成

groupId:定義目前Maven項目隸屬項目

artifactId:定義實際項目中的一個子產品

version:定義目前項目的目前版本

packaging:定義該項目的打包方式

Maven為什麼使用坐标?

Maven世界擁有大量建構,我們需要找一個用來唯一辨別一個建構的統一規範,擁有了統一規範,就可以把查找工作交給機器

依賴管理

依賴範圍

Maven核心概念詳解

傳遞性依賴

依賴範圍scope 用來控制依賴和編譯,測試,運作的classpath的關系. 主要的是三種依賴關系如下:

  1. compile: 預設編譯依賴範圍。對于編譯,測試,運作三種classpath都有效
  2. test:測試依賴範圍。隻對于測試classpath有效
  3. provided:已提供依賴範圍。對于編譯,測試的classpath都有效,但對于運作無效。因為由容器已經提供,例如servlet-api
  4. .runtime:運作時提供。例如:jdbc驅動
    Maven核心概念詳解

    依賴範圍對傳遞依賴的影響

    列是第一直接依賴,行是第二間接依賴

    Maven核心概念詳解
    可選依賴
<optional> true/false 是否向下傳
           

排除依賴

<exclusions>
    <exclusion>
        所包含坐标
           

排除依賴包中所包含的依賴關系

不需要添加版本,直接類别排除

依賴沖突

如果直接與間接依賴中包含有同一個坐标不同版本的資源依賴,以直接依賴的版本為準(就近原則)

如果直接依賴中包含有同一個坐标不同版本的資源依賴,以配置順序下方的版本為準(就近原則)

倉庫管理

生命周期

何為生命周期?

Maven生命周期就是為了對所有的建構過程進行抽象和統一

包括項目清理,初始化,編譯,打包,測試,部署等幾乎所有建構步驟

Maven三大生命周期

clean:清理項目的

default:建構項目的

site:生成項目站點的

生命周期Maven有三套互相獨立的生命周期,請注意這裡說的是“三套”,而且“互相獨立”,這三套生命周期分别是:

Clean Lifecycle 在進行真正的建構之前進行一些清理工作。

Default Lifecycle 建構的核心部分,編譯,測試,打包,部署等等。

Site Lifecycle 生成項目報告,站點,釋出站點。

再次強調一下它們是互相獨立的,你可以僅僅調用clean來清理工作目錄,僅僅調用site來生成站點。當然你也可以直接運作 mvn clean install site 運作所有這三套生命周期。

生命周期clean:

clean生命周期每套生命周期都由一組階段(Phase)組成,我們平時在指令行輸入的指令總會對應于一個特定的階段。比如,運作mvn clean ,這個的clean是Clean生命周期的一個階段。有Clean生命周期,也有clean階段。

Clean生命周期一共包含了三個階段:

pre-clean 執行一些需要在clean之前完成的工作

clean 移除所有上一次建構生成的檔案

post-clean 執行一些需要在clean之後立刻完成的工作

mvn clean 中的clean就是上面的clean,在一個生命周期中,運作某個階段的時候,它之前的所有階段都會被運作,也就是說,mvn clean 等同于 mvn pre-clean clean ,如果我們運作 mvn post-clean ,那麼 pre-clean,clean 都會被運作。這是Maven很重要的一個規則,可以大大簡化指令行的輸入。

生命周期default:

Default生命周期Default生命周期是Maven生命周期中最重要的一個,絕大部分工作都發生在這個生命周期中。這裡,隻解釋一些比較重要和常用的階段:

validate

generate-sources

process-sources

generate-resources

process-resources 複制并處理資源檔案,至目标目錄,準備打包。

compile 編譯項目的源代碼。

process-classes

generate-test-sources

process-test-sources

generate-test-resources

process-test-resources 複制并處理資源檔案,至目标測試目錄。

test-compile 編譯測試源代碼。

process-test-classes

test 使用合适的單元測試架構運作測試。這些測試代碼不會被打包或部署。

prepare-package

package 接受編譯好的代碼,打包成可釋出的格式,如 JAR 。

pre-integration-test

integration-test

post-integration-test

verify

install 将包安裝至本地倉庫,以讓其它項目依賴。

deploy 将最終的包複制到遠端的倉庫,以讓其它開發人員與項目共享。

運作任何一個階段的時候,它前面的所有階段都會被運作,這也就是為什麼我們運作mvn install 的時候,代碼會被編譯,測試,打包。此外,Maven的插件機制是完全依賴Maven的生命周期的,是以了解生命周期至關重要。

生命周期site:

Site生命周期pre-site 執行一些需要在生成站點文檔之前完成的工作

site 生成項目的站點文檔

post-site 執行一些需要在生成站點文檔之後完成的工作,并且為部署做準備

site-deploy 将生成的站點文檔部署到特定的伺服器上

這裡經常用到的是site階段和site-deploy階段,用以生成和釋出Maven站點,這可是Maven相當強大的功能,Manager比較喜歡,文檔及統計資料自動生成,很好看。

插件和目标

Maven的核心僅僅定義了抽象的生命周期,具體的任務都是交由插件完成的

每個插件都能實作多個功能,每個功能就是一個插件目标

Maven的生命周期與插件目标互相綁定,以完成某個具體的建構任務

例如compile就是插件maven-compiler-plugin的一個插件目标

<build>
    <plugins>
        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                        <execution>
                    <goals>
                        <goal>jar-no-fork</goal>
                            </goals>
                            <phase>verify</phase>
                </execution>
                </executions>
        </plugin>
    </plugins>
</build>
           

聚合繼承

何為繼承?

繼承為了消除重複,我們把很多相同的配置提取出來

例如:grouptId,version等

父工程設定為被繼承

子工程繼承父工程

省略父工程中定義的坐标除通路名稱中的所有設定,添加繼承父工程

<parent>
    <groupId>…</groupId>
    <artifactId>… </artifactId>
    <version>… </version>
    <relativePath>../父工程項目名</relativePath>
</parent>
           

父工程統一管理子工程依賴版本

<dependencyManagement>  
    <dependencies>
        //添加公共依賴包
    </dependencies>
</dependencyManagement>
           

子工程僅僅添加依賴包,無需添加版本,版本由父工程繼承而來

為了進一步便于管理,将所有的版本管理設定在一起,設定為系統屬性值

<properties>
    <junit.version>4.9</junit.version>
    ……
</properties>
           

引用使用${junit.version}格式進行,隻能在依賴範圍設定

父工程統一管理子工程依賴關系

如果所有子工程都需要依賴某些包,父工程可以通過設定依賴,将依賴關系傳遞到子工程中

<dependencies>
    //添加公共依賴包
</dependencies>
           

何為聚合?

如果我們想一次建構多個項目子產品,那我們就需要對多個項目子產品進行聚合

<modules>
    <module>../子項目名稱1</module>
    <module>../子項目名稱2</module>
     <module>../子項目名稱3</module>
</modules>
           

聚合與繼承的關系

聚合主要為了快速建構項目

繼承主要為了消除重複