Maven 學習筆記(一) —— 簡介

一. 簡介

1. 什麼是 maven

Maven 是一個項目管理工具, 包含了以下內容:

  • 一個項目對象模型, project object model
  • 一組標準集合,
  • 一個項目生命週期, project lifecycle
  • 一個依賴管理系統, dependency management system
  • 以及定義在生命週期各階段(phase)的插件(plugin)和目標(goal)

當你使用 maven 的時候, 你要用一個明確定義的項目對象模型, 然後 maven 可以應用橫切的邏輯, 這些邏輯來自一組共享的或者自定義的插件

2. 約定優於配置

“約定優於配置” 是一個簡單的概念, 系統, 類庫, 框架都應該設定一些合理的默認值, 而不要求用戶提供一些非必須的配置.

maven 默認情況下規定了項目的幾個關鍵目錄, 只要用戶將相應的文件放在這下路徑下, maven 就能正常工作. 而且 maven 最有價值的”約定”是它默認的項目生命週期, 以及一組構建和裝配軟件的通用插件.

只要遵循 maven 的這些約定, 用戶幾乎不需要添加配置, maven 就可以將剩下的事情完成.

約定優於配置的”副作用”是犧牲了一定的自由度, 但這是值得的, 遵循一定的約定, 會讓軟件開發和技術交流變得更加容易.

如果確實需要對項目進行更多的自定義設置, maven 也允許用戶修改相關的配置.

3. 插件的重用

maven 的核心其實不做什麼事情, 主要完成 pom 的解析和倉庫的管理, 實現依賴/插件的下載工作.

而具體的構建工作, 則是由插件來實現. 如果某個插件的新版本引入了新的功能特性, 那麼用戶可以通過更換這個插件的版本, 來獲取到新的特性, 而完全不需要對自己項目代碼做任何修改

4. 使用 maven

4.1.基本概念

在使用 maven 之前, 需要先了解幾個概念

  • 倉庫 repository

    存儲 maven 在項目構建過程中需要使用的一些構件, 包括依賴, 插件等, 有遠程倉庫和本地倉庫

    maven 在構建過程中會先從本地獲取需要的構件, 如果本地沒有找到, 則會從遠程倉庫獲取

  • 座標 coordinate

    從倉庫中定位一個構件需要提供的信息, 包括 GroupId-組織, ArtifactId-項目, Packaging-打包類型, Version-版本號

    在聲明自己項目的時候, 使用如下格式聲明座標

    <groupId>com.loyofo</groupId>
    <artifactId>mutilmvn</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    而在引用依賴的時候, 則是使用如下格式, 注意其中的 packaging 換成了 type

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <!-- type 默認爲 jar, 可省略 -->
      <type>jar</type>
      <version>3.8.1</version>
    </dependency>

    其中的 packaging, 或者說 type, 默認爲jar, 這也是依賴真正要用的部分, 因此 maven 座標通常也會稱爲 GAV 座標.

    xml 格式比較冗長, 有的地方也會有縮略寫法, 如 gradle, 縮略格式將 GAPV 按順序排列, 用冒號 : 分隔, 如下:

    groupId: artifactId: packing: version

  • 插件 plugin

    maven 依靠插件來完成項目構建工作, 這些插件可以通過座標從倉庫中獲取. 如下所示

    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
    </plugin>
  • 目標 goal

    目標, 即一個插件需要完成的某個工作任務. maven 對項目的構建工作, 就是通過執行一個個插件目標來完成的,

    目標是插件提供的, 某個插件的某個目標, 可以用如下格式來確定

    plugin: goal

  • 生命週期階段 phase

    生命週期中的某個階段, 通常會跟某個插件目標綁定在一起, 執行這個階段的時候, 就是執行這個插件的目標

  • 生命週期 lifeCycle

    項目構建的全過程, 稱爲 maven 項目的生命週期, 由一個個的生命週期階段組成,

    當生命週期階段依次執行時, 就會完成一個個的插件目標, 完成 編譯-測試-打包-發佈 的一系列工作

  • 項目對象模型 pom

    項目描述的模型, 記錄了項目的座標, 許可信息, 開發者信息, 依賴, 插件, profile 等內容,

    修改 pom.xml 的內容, 可以指導 maven 如何去完成構建工作.

4.1. 運行 maven

1)通過插件目標執行

maven 的具體工作其實是一個個的插件目標, 如果想讓 maven 執行某個工作, 可以直接通過命令執行插件目標

mvn 插件: 目標

2) 通過生命週期(階段)執行

maven 的生命週期是一個插件目標的序列, 當我們指定讓 maven 執行到生命週期中的某一個階段時, maven 將會按照生命週期的順序, 依次完成前導的各個階段, 即完成了一系列的插件目標, 然後在完成指定階段所綁定的插件目標後結束.

mvn 生命週期階段

3) 帶參數執行

有時候需要修改構建工作, 比如修改參數, 或指定 profile, 可以在命令中加入參數來實現

其中 -D 表示修改參數, -P 表示激活指定的配置文件

mvn 命令 -D參數 -P配置profile

4) Ide 工具

a. eclipse + m2e

eclipse 集成了 m2e 插件, 通過右鍵的 maven build... , 設置命令後執行

這裏寫圖片描述

b. idea + maven support

idea 自帶了一個 maven support 的插件, 默認顯示在界面右側邊欄, 可以快速執行某個生命週期階段, 切換profile, 或是運行某個插件, 也可以自己輸入命令執行

這裏寫圖片描述

4.3. 使用 Maven Help 插件

maven help 插件有四個目標:

  • help: active-profiles

    列出當前構建中的有效 profile, 並指出該 profile 是在什麼地方定義的

  • help: effective-pom

    顯示當前構建的實際 pom, 包含活動的 profile

  • help: effective-settings

    顯示項目的實際 settings, 包括全局 settings, 和用戶 settings

  • help: describe

    描述插件的屬性, 相當於插件的幫助文檔, 不需要在項目目錄下運行, 但需要-Dplugin指定要查詢的插件

    使用插件的前綴查詢

    mvn help:describe -Dplugin=help

    使用插件的座標查詢, 其中 version 是可選的

    mvn help:describe -Dplugin=Gid: Aid: Ver

    如果需要更詳細的介紹, 可以添加 -Dfull 參數

    mvn help:describe -Dplugin=help -Dfull

    也可以查看插件某個目標的介紹, 使用 -Dmojo 參數傳入

    mvn help:describe -Dplugin=compiler -Dmojo=compile -Dfull

5. 項目對象模型

5.1. pom 的內容

這裏寫圖片描述

pom 包含四類描述和配置

  • 項目總體信息

    包含一個項目的名稱, url, 發起組織, 項目開發者和貢獻者, 許可證等

  • 構建設置

    可以在這一部分自定義 maven 的構建行爲, 可以更改源碼和測試代碼的位置, 添加插件, 綁定插件到生命週期, 自定義站點生成參數等

  • 構建環境

    構建環境包含了一些能在不同使用環境中激活的 profile, 比如在開發環境和生產環境使用不同的數據庫配置信息等

  • pom 關係

    一個項目很少孤立存在, 它會以來與其他項目, 可能從父項目繼承 pom 設置, 要定義自身的座標, 還可能包含子模塊

5.2. 超級 pom

maven 定義了一個超級 pom, 所有項目都會從超級 pom 中繼承設置, 超級 pom 中的設置, 就是maven的”約定”部分, 遵循約定有利於項目的分享和交流, 如非必要不應修改相關配置.

  • 超級 pom 中定義了默認的中央倉庫, 但關閉了 SNAPSHOT , 用戶可以從中央倉庫獲取依賴, 但不能獲取到 SNAPSHOT 的開發中版本.
  • 如果想使用 maven 私服, 或者其他的第三方倉庫, 可以在 settings.xml 或是項目的 pom.xml 中自定義倉庫設置.
  • 中央倉庫也包含插件, 同樣關閉了 SNAPSHOT 版本. 爲了兼容舊項目, 超級 pom 聲明瞭舊版的插件版本, 且默認不更新. 如果確定需要使用新版本的插件, 請在自己的項目 pom.xml 中聲明
  • build 元素設置了 maven 標準目錄

5.3. 有效 pom

所有 maven 項目的 pom 都繼承自超級 pom, 同時還會從settings.xml , 父項目 pom, profile 中獲取設置, 最終得到一個混合了各個 pom 設置的有效 pom, 如果想查看項目最終有效的 pom, 可以運行 help 插件的目標獲取

mvn help: effective-pom

5.4. 自定義 pom

可以在 pom 中進行各種構建設置, 典型的 pom 結構如下

pom支持的完整內容

<project>
    <!-- 當前pom的版本, 一般爲4.0.0 -->
    <modelVersion/>

    <!-- 聲明當前項目所屬的父項目 -->
    <parent>
        <groupId/>
        <artifactId/>
        <version/>
        <relativePath/>
    </parent>

    <!-- 聲明當前項目的座標 -->
    <groupId/>
    <artifactId/>
    <version/>
    <packaging/>

    <!-- 聲明當前項目的描述 -->
    <name/>
    <description/>
    <url/>

    <!-- 聲明發布的相關信息, 發佈到什麼地方 -->
    <distributionManagement/>

    <!-- 聲明當前模塊包含哪些子模塊 -->
    <modules>
        <module/>
    </modules>

    <!-- 自定義變量 -->
    <properties>
        <key>value</key>
    </properties>

    <!-- 聲明依賴, 但並未真正加載, 要用的話需要在 dependencies 中添加 -->
    <dependencyManagement>
        <dependencies>
            <dependency/>
        </dependencies>
    </dependencyManagement>

    <!-- 添加依賴, 如果在 dependencies 中有聲明, 則可以只寫 Gid 和 Aid -->
    <dependencies>
        <dependency/>
    </dependencies>

    <!-- 添加倉庫 -->
    <repositories>
        <repository/>
    </repositories>

    <!-- 添加插件倉庫 -->
    <pluginRepositories>
        <pluginRepository/>
    </pluginRepositories>

    <!-- 構建設置 -->
    <build>
        <!-- 添加資源目錄 -->
        <resources>
            <resource/>
        </resources>

        <!-- 添加測試資源目錄 -->
        <testResources>
            <testResource/>
        </testResources>

        <!-- 構建後文件的位置和文件名 -->
        <directory/>
        <finalName/>

        <!-- 資源過濾器, 可以替換資源目錄中文件中的變量 -->
        <filters/>

        <!-- 聲明插件, 但未真正加載, 需要在 plugins 中添加 -->
        <pluginManagement>
            <plugins>
                <plugin/>
            </plugins>
        </pluginManagement>

        <!-- 添加插件, 如果在 pluginManagement 中有聲明, 可以只寫 Gid 和 Aid -->
        <plugins>
            <plugin/>
        </plugins>
    </build>

    <!-- 添加 profiles -->
    <profiles>
        <profile/>
    </profiles>
</project>

5.5. 項目版本號

maven 建議採用以下格式定義版本號

<主版本號>. <次版本號>. <增量版本號>-<限定版本號>

1.3.5, 1.0.2-alpha

當按照這個格式聲明項目版本時, 則可以在以後引用依賴時使用”依賴版本界限”對依賴版本進行限制.

如果不符合這個規則, 則會使用字符串比較.

SNAPSHOT - 快照

對於 SNAPSHOT 的開發版本, maven 會在發u這個組件時將該符號展開成時間戳, 即發佈了該項目的一個快照版本.

LATEST, RELEASE

LATEST: 表示某個特定構件的最新發布版本(如果啓用了 snapshot 庫則是最新快照版本)

RELEASE: 表示倉庫中最後一個非快照的版本

不建議在項目中使用這種不確定的版本, 可能在版本變換時會出現意想不到的問題.

5.6. 屬性引用

pom 裏面可以使用 ${...} 來引用一個屬性, 在構建時會將有效的值替換到引用處, 可以在有效 pom 中看到

1) 聲明屬性變量

通常會使用 properties 元素來聲明一些變量, 就可以在 pom 中其他地方進行引用

<KEY> VALUE </KEY>

<properties>
    <spring.version>4.3.3.RELEASE</spring.version>
</properties>

2) 預設屬性變量

除了用戶自己定義的屬性變量, maven 也有幾個預設的屬性

  • env

    ${env.xxx} 屬性暴露了操作系統或者 shell 的環境變量, 比如 ${env.PATH} 會被替換成系統的 PATH 變量

  • project

    ${project.xxx} 變量暴露了當前 pom, 可以使用 . 路徑來引用 pom 中定義的屬性值

    ${project.groupId} 引用了當前項目的 GroupId

  • settings

    ${settings.xxx} 暴露了 maven settings 的信息, 可以引用在 setting.xml 中定義的屬性值

3) 引用屬性變量

使用 ${...} 對已聲明的屬性進行引用, 將會在構建時替換成真實值

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
</dependency>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章