day47_Maven學習筆記

  • Maven的課程計劃
    • 一、Maven的介紹
    • 二、Maven的安裝和配置
    • 三、建立Maven工程
    • 四、M2Eclipse插件
    • 五、Maven的核心概念
      • a)座標
      • b)依賴管理
      • c)生命週期
      • d)Maven 插件
      • e)繼承
      • f)聚合
    • 六、Maven的倉庫管理

1、Maven的介紹

1.一、項目開發中遇到的問題

  • 一、都是一樣的代碼,爲何在個人機器上能夠編譯執行,而在他的機器上就不行?
  • 二、爲何在個人機器上能夠正常打包,而配置管理員卻打不出來?
  • 三、項目組加入了新的人員,我要給他說明編譯環境如何設置,可是讓我撓頭的是,有些細節我也記不清楚了。
  • 四、個人項目依賴一些jar包,我應該把他們放哪裏?放源碼庫裏嗎?
  • 五、這是我開發的第二個項目,仍是須要上面的那些jar包,再把它們複製到我當前項目的svn庫裏吧。
  • 六、如今是第三次,再複製一次吧。。。
    • 這樣真的好嗎?
  • 七、我寫了一個數據庫相關的通用類,而且推薦給了其餘項目組,如今已經有五個項目組在使用它了,今天我發現了一個bug,並修正了它,我會把jar包經過郵件發給其餘項目組。
    • 這不是一個好的分發機制,太多的環節可能致使出現bug。
  • 八、項目進入測試階段,天天都要向測試服務器部署一版。每次都手動部署,太麻煩了。

1.二、什麼是Maven

  Maven是基於項目對象模型(POM),能夠經過一小段描述信息來管理項目的構建,報告和文檔的軟件項目管理工具
  Maven是一個跨平臺的項目管理工具,它是使用java開發的,它要依賴於jdk1.6及以上。主要服務於基於Java平臺的項目構建依賴管理項目信息管理javascript

  • Maven主要有兩個功能:
      一、項目構建
      二、依賴管理
      依賴指的就是jar包。

1.三、什麼是項目構建

項目構建以下圖所示:php


構建過程以下圖所示:

1.四、項目構建的方式

  • 一、Eclipse
    • 手工操做較多,項目的構建過程都是獨立的,相對來講,步驟比較零散,很難一步完成。好比:編譯、測試、部署等。
    • 開發時每一個人的IDE配置都不一樣,很容易出現本地代碼換個地方編譯就出錯。
  • 二、Ant
    • Ant只是一個項目構建工具,它沒有集成依賴管理。
    • Ant在進行項目構建時,它能夠經過一些配置來完成項目構建,這些配置要明確的告訴Ant,即:它沒有對項目目錄結構進行約定,須要手動指定源文件、類文件等目錄地址。同時它執行task時,須要顯示指定依賴的task,這樣會形成大量的代碼重複。
  • 三、`Maven`
    • Maven不只是一個項目構建工具,更是一個項目管理工具。它在項目構建工程中,比Ant更全面,更靈活。
    • 經過使用Maven,能夠對項目進行快速簡單的構建,它不須要告訴Maven不少信息,可是須要安裝Maven的規範去進行代碼的開發。也就是說Maven是有約束的。
    • Maven在進行項目構建時,它對項目目錄結構擁有約定,知道你的源代碼在哪裏,類文件應該放到哪裏去。
    • Maven擁有生命週期的概念,Maven的生命週期是有順序的,在執行後面的生命週期的任務時,不須要顯示的配置前面任務的生命週期。
      • 例如:執行 mvn install 就能夠自動執行編譯、測試、打包等構建過程。

1.五、Maven 的概念模型

以下圖所示:css

2、Maven的安裝和配置

2.一、下載Maven

  • 官方網站:https://maven.apache.org/
  • 下載網址:https://maven.apache.org/download.cgi
  • 下載界面:
  • 本課程使用的maven的版本爲3.5.4,軟件發展趨勢:對於高版本的Maven,之後都會整合到IDE中去。
  • Maven是使用java開發,須要安裝jdk1.6以上,推薦使用1.8

2.二、Maven的安裝

  • 第一步:安裝jdk,要求1.6或以上版本。
  • 第二步:把maven解壓縮,解壓目錄最好不要有中文和空格。
  • 第三步:配置maven的系統環境變量MAVEN_HOME
  • 第四步:配置環境變量Path,將%MAVEN_HOME%\bin加入Path中,在Windows中必定要注意要用分號與其餘值隔開。
  • 第五步:驗證是否安裝成功,打開cmd窗口,輸入命令:mvn –v,出現以下界面,表示安裝成功。

2.三、Maven的配置

  • Maven有兩個settings.xml配置文件:一個是全局配置文件(默認),一個是用戶配置文件。

2.3.一、全局配置(默認)

在maven安裝目錄的conf目錄裏面有一個settings.xml文件,這個文件就是maven的全局配置文件。
該文件中配置了maven本地倉庫的地址,以下圖所示:html


localRepository:用戶倉庫,用於檢索依賴包路徑。
默認在系統的用戶目錄下的m2/repository中,該目錄是本地倉庫的目錄。以下圖所示:

2.3.二、用戶配置

用戶配置文件的地址:~/.m2/settings.xml是用戶的配置文件(默認沒有該文件,須要將全局配置文件拷貝過來再進行修改),其中~表示當前用戶路徑C:\Users[UserName]。以下圖所示:java


注意:通常本地倉庫的地址不使用默認配置,一般狀況下須要在用戶配置中,配置新的倉庫地址。
配置步驟以下:
  第一步:建立一個本地倉庫目錄,好比:D:\learn\Java\apache-maven-3.5.4\repository。
  第二步:複製maven的全局配置文件到~/.m2目錄下,即建立用戶配置文件
  第三步:修改maven的用戶配置文件。以下圖所示:

注意:用戶級別的倉庫在全局配置中一旦設置,全局配置將再也不生效,轉而使用用戶所設置的倉庫,不然使用全局配置文件中的默認路徑倉庫。

3、建立Maven工程

3.一、Maven的工程結構

詳解以下:程序員

Project
  |-src(源碼包)
  |
   |-main(正常的源碼包)
  |
   |  |-java         —— 存放項目的.java文件的目錄
  |   |  |-resources    —— 存放項目資源文件的目錄,例如:spring, hibernate等配置文件
  |
   |-test(測試的源碼包)
  |
      |-java         —— 存放全部測試.java文件的目錄,例如:JUnit測試類
  |
      |-resources    —— 存放測試資源文件的目錄
  |
-target              —— 目標文件輸出位置,例如:.class文件、.jar文件、.war文件、報告等信息
  |-pom.xml             ——maven項目核心配置文件,即maven工程的描述文件

3.二、Maven的工程建立

  • 第一步:根據maven的工程結構來建立helloMaven工程
  • 第二步:建立HelloWorld.java
    在src/main/java/com/itheima/maven目錄下新建文件HelloMaven.java
    示例代碼以下:
package com.itheima.maven;

public class HelloMaven {
    public String sayHello(String name) {
        return "hello " + name;
    }
}
  • 第三步:建立TestHelloWorld.java
    在src/test/java/com/itheima/maven目錄下新建文件TestHelloMaven.java
    示例代碼以下:
package com.itheima.maven;

import org.junit.test;
import static junit.framework.Assert.*;

public class TestHelloMaven {
    @Test
    public String testSayHello() {
        HelloMaven hw = HelloMaven();
        String result = hw.sayHello("maven");
        assertEquals("hello maven", result);
    }
}
  • 第四步:配置pom.xml
    示例代碼以下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- 版本:4.0.0 -->
    <modelVersion>4.0.0</modelVersion>
    <!-- 組織名稱:暫時使用 組織名稱+項目名稱 做爲組織名稱 -->
    <!-- 組織名稱:實際名稱 按照訪問路徑規範設置,一般以功能做爲名稱:eg: junit spring -->
    <groupId>com.itheima.maven</groupId>
    <!-- 項目名稱 -->
    <artifactId>HelloMaven</artifactId>
    <!-- 當前項目版本號:同一個項目開發過程當中能夠發佈多個版本,此處標示0.0.1版 -->
    <!-- 當前項目版本號:每一個工程發佈後能夠發佈多個版本,依賴時調取不一樣的版本,使用不一樣的版本號 -->
    <version>0.0.1</version>
    <!-- 名稱:可省略 -->
    <name>Hello</name>

    <!-- 依賴關係 -->
    <dependencies>
        <!-- 依賴設置 -->
        <dependency>
            <!-- 依賴組織名稱 -->
            <groupId>junit</groupId>
            <!-- 依賴項目名稱 -->
            <artifactId>junit</artifactId>
            <!-- 依賴版本名稱 -->
            <version>4.9</version>
            <!-- 依賴範圍:test包下依賴該設置 -->
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

注意事項:web


到此maven工程建立成功。

3.三、Maven的命令使用

Maven的命令須要在pom.xml所在目錄中執行如下命令。spring

3.3.1mvn compile
    執行 mvn compile 命令,完成編譯操做。
    執行完畢後,會生成target目錄和maven-status目錄(新版本出現的),該目錄中存放了編譯後的字節碼文件。

3.3.2mvn clean
    執行 mvn clean 命令
    執行完畢後,會將target目錄刪除。

3.3.3mvn test
    執行 mvn test 命令,該命令會將test目錄中的源碼進行編譯,完成單元測試操做。
    執行完畢後,會在target目錄中生成三個文件夾:maven-status(舊版本是surefire)、surefire-reports(測試報告)、test-classes(測試的字節碼文件)

3.3.4mvn package
    執行 mvn package 命令,完成打包操做。
    執行完畢後,會在target目錄中生成一個文件,該文件多是jarwar。本例中是:helloMaven-0.0.1.jar

3.3.5mvn install 
    執行 mvn install 命令,完成將打好的jar包安裝到本地倉庫的操做。
    執行完畢後,會在本地倉庫中出現安裝後的jar包,方便其餘工程引用。

3.3.6mvn clean compile
    cmd 中錄入 mvn clean compile 命令
    組合指令,先執行clean,再執行compile,一般應用於上線前執行,清除測試類。

3.3.7mvn clean test
    cmd 中錄入 mvn clean test 命令
    組合指令,先執行clean,再執行test,一般應用於測試環節。

3.3.8mvn clean package
    cmd 中錄入 mvn clean package 命令
    組合指令,先執行clean,再執行package,將項目打包,一般應用於發佈前。
    執行過程:
        清理 --> 清空環境
        編譯 --> 編譯源碼
        測試 --> 測試源碼
        打包 --> 將編譯的非測試類打包

3.3.9mvn clean install
    cmd 中錄入 mvn clean install 查看倉庫,當前項目被髮布到倉庫中。
    組合指令,先執行clean,再執行install,將項目打包,一般應用於發佈前。
    執行過程:
        清理 --> 清空環境
        編譯 --> 編譯源碼
        測試 --> 測試源碼
        打包 --> 將編譯的非測試類打包
        部署 --> 將打好的包發佈到資源倉庫中

4、M2Eclipse插件

  • M2Eclipse是eclipse中的Maven插件。(低版本的ecplise須要手動安裝,高版本的eclipse自帶,本博主用的是高版本的eclipse
  • M2Eclipse是MyEclipse中自帶的Maven插件。

4.一、演示:安裝配置M2Eclipse插件

  • 第一步:將如下包中的插件進行復制
  • 第二步:粘貼到eclipse中的dropins目錄中
  • 第三步:查看eclipse中是否有maven插件
    MyEclipse中自帶的Maven插件截圖:

    手動安裝M2Eclipse插件後,截圖同上。
  • 第四步:設置maven的安裝目錄
  • 第五步:設置maven的用戶配置,由於咱們經過eclipse方式使用maven,因此用戶配置文件咱們想放哪就放哪!!!注意:這種方式須要指定用戶配置文件的目錄便可。

4.二、經過骨架建立MavenFirst工程-Java工程

經過骨架建立maven工程,建立的是Java工程。sql

  • 第一步:選擇 new --> maven --> Maven Project
  • 第二步:點擊 next
  • 第三步:點擊 next,選擇maven的工程骨架,這裏咱們選擇先以quickstart爲例
  • 第四步:點擊 next

    輸入GroupId、ArtifactId、Version、Package信息點擊finish完成
  • 第五步:點擊 finish,建立maven工程,建立成功以下圖所示:
  • 第六步:根據工程骨架建立的maven工程沒有源resources目錄,須要手動建立,以下圖所示:
    /MavenFirst/src/main/resources

    /MavenFirst/src/test/resources
  • 第七步:建立 MavenFirst.java
    在src/main/java中建立com.itheima.maven包,而後建立MavenFirst.java
    示例代碼以下:
package com.itheima.maven;

public class MavenFirst {

    public String sayHello(String name) {
        return "hello " + name;
    }
}
  • 第八步:建立 TestMavenFirst.java
    在src/test/java中建立com.itheima.maven包,而後建立TestMavenFirst.java
    示例代碼以下:
package com.itheima.maven;

import org.junit.Assert;
import org.junit.Test;
// import static junit.framework.Assert.*;

public class TestMavenFirst {

    @Test
    public void testSayHello() {
        MavenFirst first = new MavenFirst();
        String result = first.sayHello("maven");
        Assert.assertEquals("hello maven", result);
    }
}
  • 第九步:執行 maven命令進行測試
    在MyEclipse的maven插件中執行maven命令,須要在maven工程或者pom.xml文件上點擊右鍵,選擇Run as --> Maven build..,以下圖所示:

    能夠在菜單中看到maven經常使用的命令已經以菜單的形式出現。
    例如:
      Maven build
      Maven build…
      Maven clean
      Maven install
      Maven package
      Maven test
    其中:
    Maven build和Maven build… 並非Maven的命令。
    Maven build…只是提供一個命令輸入功能,能夠在此功能中輸入自定義的Maven命令。以下圖所示:
    Maven build的功能就是執行上次自定義命令。

4.三、不經過骨架建立MavenSecond工程(推薦方式)

  經過選擇骨架建立maven工程,每次選擇骨架時都須要聯網下載,若是網絡不通或者較慢的狀況下會有很長時間的等待。使用非常不方便,因此建立工程時能夠不選擇骨架直接建立工程。數據庫

  • 第一步:選擇 new --> maven --> Maven Project
    截圖同上。
  • 第二步:點擊 next
  • 第三步:點擊 next
  • 第四步:點擊 finish,完成maven工程建立。以下圖所示:
  • 第五步:修改pom文件
    在MavenSecond工程中依賴使用MavenFirst工程的代碼
    示例代碼以下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima.maven</groupId>
    <artifactId>MavenSecond</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <!-- 在MavenSecond工程中依賴使用Junit的代碼 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </dependency>
        <!-- 同理:在MavenSecond工程中依賴使用MavenFirst工程的代碼 -->
        <dependency>
            <groupId>com.itheima.maven</groupId>
            <artifactId>MavenFirst</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  • 第六步:建立 MavenSecond.java
    在src/main/java中建立com.itheima.maven包,而後建立MavenSecond.java
    示例代碼以下:
package com.itheima.maven;

public class MavenSecond {
    public String sayHello(String name) {
        MavenFirst first = new MavenFirst();
        return first.sayHello(name);
    }
}

注意:會出現一個問題,以下圖所示:


解決辦法:
辦法一:
一、這是由於未Update Project…,而且項目的clean與maven的clean不一樣步的結果

二、選擇要更新的項目

三、maven項目,clean build以後;MyEclipse也須要 Project --> Clean… 下,以下圖所示:

錯誤消失了,感受整個世界都清爽了許多,以下圖所示:
  • 第七步:建立 TestMavenSecond.java
    在src/test/java中建立com.itheima.maven包,而後建立TestMavenSecond.java
    示例代碼以下:
package com.itheima.maven;

import org.junit.Assert;
import org.junit.Test;

public class TestMavenSecond {
    @Test
    public void testSayHello() {
        MavenSecond second = new MavenSecond();
        String result = second.sayHello("maven");
        Assert.assertEquals("hello maven", result);
    }
}
  • 第八步:執行 maven命令進行測試工程
    在MyEclipse的maven插件中執行maven命令,須要在maven工程或者pom.xml文件上點擊右鍵,選擇Run as --> Maven test,以下圖所示:

    若是MavenFirst工程沒有安裝,則會出現如下錯誤:
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.itheima.maven:MavenSecond >--------------------
[INFO] Building MavenSecond 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[WARNING] The POM for com.itheima.maven:MavenFirst:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.884 s
[INFO] Finished at: 2018-09-24T12:30:47+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project MavenSecond: Could not resolve dependencies for project com.itheima.maven:MavenSecond:jar:0.0.1-SNAPSHOT`Could not find artifact com.itheima.maven:MavenFirst:jar:0.0.1-SNAPSHOT` -> [Help 1]
[ERROR
[ERRORTo see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR
[ERRORFor more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

提示找不到MavenFirst的jar包。當系統運行時是從本地倉庫中找依賴的jar包的,因此必須先MavenFirst安裝才能正常運行,須要在MavenFirst工程上運行 mvn install命令安裝到本地倉庫。而後在MavenSecond工程上再次運 mvn test 命令測試工程。
正確的測試結果以下:

[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------< com.itheima.maven:MavenSecond >--------------------
[INFO] Building MavenSecond 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ MavenSecond ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ MavenSecond ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been setusing platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\learn\Java\MyEclipse\Workspaces\MyEclipse 2017 CI\MavenSecond\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ MavenSecond ---
[WARNINGUsing platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ MavenSecond ---
[INFO] Changes detected - recompiling the module!
[WARNINGFile encoding has not been setusing platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\learn\Java\MyEclipse\Workspaces\MyEclipse 2017 CI\MavenSecond\target\test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ MavenSecond ---
[INFO] Surefire report directory: D:\learn\Java\MyEclipse\Workspaces\MyEclipse 2017 CI\MavenSecond\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.itheima.maven.TestMavenSecond
Tests run: 1, Failures: 0Errors0, Skipped: 0Time elapsed: 0.06 sec

Results :

Tests run: 1, Failures: 0Errors0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time3.482 s
[INFO] Finished at2018-09-24T12:33:39+08:00
[INFO] ------------------------------------------------------------------------

5、Maven的核心概念

5.一、座標

  • 什麼是座標?
    在平面幾何中座標(x,y)能夠標識平面中惟一的一點。在maven中座標就是爲了定位一個惟一肯定的jar包。
    Maven世界擁有大量構建,咱們須要找一個用來惟一標識一個構建的統一規範,擁有了統一規範,就能夠把查找工做交給機器。
  • Maven座標的主要組成
    groupId:定義當前Maven組織名稱
    artifactId:定義實際項目名稱
    version:定義當前項目的當前版本

5.二、依賴管理

  • 就是對項目中 jar包的管理。能夠在pom文件中定義jar包的GAV座標,管理依賴。
  • 依賴聲明主要包含以下元素:
    <dependencies>
        <!-- 在MavenSecond工程中依賴使用Junit的代碼 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </dependency>
        <!-- 同理:在MavenSecond工程中依賴使用MavenFirst工程的代碼 -->
        <dependency>
            <groupId>com.itheima.maven</groupId>
            <artifactId>MavenFirst</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

5.2.一、依賴範圍


詳解以下:
其中依賴範圍scope 用來控制`依賴`和`編譯、測試、運行的classpath的關係`,主要的是三種依賴關係以下:
    1.compile:默認編譯依賴範圍。對於編譯、測試、運行三種classpath都有效。
    2.test:測試依賴範圍。只對於測試classpath有效。
    3.provided:已提供依賴範圍。對於編譯、測試的classpath都有效,但對於運行的classpath無效。由於容器已經提供,例如:servlet-api
    4.runtime:運行時依賴範圍。例如:jdbc驅動。

5.2.二、依賴傳遞

若是C中使用B,B中使用A,則稱B是C的直接依賴,而稱A是C的間接依賴。
    C->B,B->A
    C直接依賴B
    C間接依賴A
  • 示例:建立MavenThird工程演示依賴傳遞(不經過骨架建立)
    • 第一步:建立MavenThird工程
    • 第二步:建立MavenThird.java
      • 在src/main/java中建立com.itheima.maven包,而後建立MavenThird.java
    • 第三步:建立TestMavenThird.java
      • 在src/test/java中建立com.itheima.maven包,而後建立TestMavenThird.java
  • 分析第一間接依賴和第二直接依賴,以下圖所示:
  • 依賴範圍對依賴傳遞的影響:即依賴範圍傳遞,以下圖所示:

詳解以下:

左邊第一列表示第一直接依賴範圍
上面第一行表示第二直接依賴範圍
中間的交叉單元格表示傳遞性依賴範圍。

總結:
    當第二直接依賴的範圍是compile的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致。
    當第二直接依賴的範圍是test的時候,依賴不會得以傳遞。
    當第二直接依賴的範圍是provided的時候,只傳遞第一直接依賴範圍也爲provided的依賴,且傳遞性依賴的範圍一樣爲provide。
    當第二直接依賴的範圍是runtime的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致,但compile例外,此時傳遞的依賴範圍爲runtime。

5.2.三、依賴衝突

  • 在maven中存在兩種依賴衝突方式:一種是跨pom文件的依賴衝突;一種是同一個pom文件中的依賴衝突。
    • 跨pom文件的依賴衝突
      若是MavenFirst工程的pom文件中依賴來junit的4.9版本,因此MavenSecond和MavenThird中都是使用了4.9版本。

      依賴的jar包以下:

      若是MavenSecond工程中從新依賴junit的4.8版本,那麼MavenSecond和MavenThird中都是使用了4.8本,這體現來依賴的`就近使用原則`。

      依賴的jar包以下:
    • 同一個pom文件中的依賴衝突

      依賴的jar包以下:

5.2.四、可選依賴

    `<optional>` 標籤表示該依賴是否可選,默認是false
    能夠理解爲,若是爲true,則表示該依賴不會傳遞下去,若是爲false,則會傳遞下去。
    可選依賴很差使,由於有的工程想要該依賴,有的工程不想要該依賴,而你在源頭就已經設置成可選的了,這樣就致使很差使了。

以下圖所示:

5.2.五、排除依賴

    `<exclusions>`標籤能夠排除依賴。排除依賴包中所包含的依賴關係,`不須要添加版本號`
    若是在本次依賴中有一些多餘的jar包也被傳遞依賴過來,若是想把這些jar包排除的話能夠配置exclusions進行排除。
    這種方式更靈活,在實際的項目中也是這種方式。

以下圖所示:

5.三、生命週期

  • 什麼是生命週期?
    Maven生命週期就是爲了對全部的構建過程進行抽象和統一。包括項目清理初始化編譯打包測試部署等幾乎全部構建步驟。
    生命週期能夠理解爲構建工程的步驟。
  • 在Maven中有三套相互獨立的生命週期,請注意這裏說的是「三套」,並且「相互獨立」,這三套生命週期分別是:
    • Clean Lifecycle:在進行真正的構建以前進行一些清理工做。
    • Default Lifecycle:構建的核心部分,編譯、測試、打包、部署等等。
    • Site Lifecycle:生成項目報告、站點、發佈站點。
  • 生命週期是由多個階段(Phase)組成。每一個階段都是一個完整的功能,好比mvn clean中的clean就是一個階段。
  • 再次強調一下它們是相互獨立的,你能夠僅僅調用clean來清理工做目錄,僅僅調用site來生成站點。
    固然你也能夠直接運行 mvn clean install site 運行全部這三套生命週期。

5.3.一、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很重要的一個規則,能夠大大簡化命令行的輸入。

5.3.二、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的生命週期的,所以理解生命週期相當重要。

5.3.三、Site生命週期:生成項目站點

pre-site            執行一些須要在生成站點文檔以前完成的工做 
`site`              生成項目的站點文檔 
post-site           執行一些須要在生成站點文檔以後完成的工做,而且爲部署作準備 
`site-deploy`       將生成的站點文檔部署到特定的服務器上

這裏常常用到的site階段和site-deploy階段,用以生成和發佈Maven站點,這但是Maven至關強大的功能,Manager比較喜歡,文檔及統計數據自動生成,很好看。
可是通常在工程中不多使用個,領導要看的是更簡單、更直接東西,好比:作的PPT、報表等。

5.四、Maven 插件

  Maven的核心僅僅定義了抽象的生命週期,具體的任務都是交由插件完成的。每一個插件都能實現一個功能,每一個功能就是一個插件目標。Maven的生命週期與插件目標相互綁定,以完成某個具體的構建任務。
  插件(plugin),每一個插件都能實現一個階段的功能。Maven的核心是生命週期,可是生命週期至關於主要指定了maven命令執行的流程順序,而沒有真正實現流程的功能,功能是有插件來實現的。
  好比:compile就是插件maven-compiler-plugin的一個插件目標。

5.4.一、Maven 編譯插件

編譯使用的jdk是由Maven編譯插件指定,若是咱們沒有指定編譯用的jdk版本,當咱們修改了編譯用的jdk版本,一更新Maven項目,就會還原回去,還原成默認配置的編譯用的jdk版本。以下圖所示:


咱們如今要配置編譯插件:指定編譯用的jdk版本
示例代碼以下:
/MavenFirst/pom.xm
    <build>
        <plugins>
            <!-- 配置編譯插件:指定編譯用的jdk版本  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

示例代碼截圖:


而後咱們保存修改配置文件後,在工程上點擊右鍵選擇Maven --> Update Project…,
即再次更新Maven項目,發現編譯用的jdk版本變了,以下圖所示:

5.4.二、Tomcat 插件--Web工程

  • 若是使用maven的tomcat插件的話,那麼本地則不須要安裝tomcat了。

使用maven建立一個Web工程,不使用骨架。步驟以下:

  • 第一步:建立方式:不選用骨架
  • 第二步:將打包方式選擇爲war,以下圖所示:
  • 第三步:點擊finish,Web工程建立成功。
  • 第四步:在/MavenWeb/src/main/webapp建立WEB-INF目錄以及在WEB-INF目錄建立web.xml文件

    web.xml內容以下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

    id="WebApp_ID" version="3.1">

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>
  • 第五步:在webapp下建立index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    第一個Maven Web工程!
</body>
</html>
  • 第六步:使用tomcat插件運行web工程
    右鍵項目 --> Run As --> Maven build…默認輸入tomcat:run去使用tomcat插件來啓動web工程,可是默認的tomcat插件使用的tomcat版本是tomcat6。而目前主流的tomcat是使用的tomcat7或tomcat8或tomcat9,因此須要手動配置tomcat插件。
    即:
    tomcat:run 運行tomcat6(默認)
    tomcat7:run 運行tomcat7(推薦,可是須要添加插件)

添加插件代碼以下:
/MavenWeb/pom.xml

    <build>
        <plugins>
            <plugin>
                <!-- 配置tomcat7插件 -->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8085</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>

使用tomcat7來運行web工程,它的命令是:tomcat7:run
效果截圖以下:

5.五、繼承

在maven中的繼承,指的是pom文件的繼承。繼承是爲了消除重複,能夠把不少相同的配置提取出來。例如:grouptId,version等。

5.5.一、建立父工程-不使用骨架

建立maven工程,不使用骨架,以下圖所示:


/MavenParent/pom.xml文件截圖以下:

5.5.二、建立子工程-不使用骨架

  • 建立子工程方式有兩種:
    • 方式一:建立新工程爲子工程,在建立時設置父工程的GAV。
    • 方式二:修改原有的工程爲子工程,在子工程的pom.xml文件中手動添加父工程的GAV。

咱們使用方式一:


/MavenSub/pom.xml文件截圖以下:

同理:
方式二:原有工程繼承父工程只須要在pom文件中添加parent節點便可。

5.5.三、父工程統一依賴jar包

在父工程中對jar包進行依賴,在子工程中都會繼承此依賴。


子工程依賴效果以下圖所示:


5.5.四、父工程統一管理版本號

Maven使用dependencyManagement 標籤來管理依賴的版本號。
注意:此處只是定義依賴jar包的版本號,並不實際依賴。若是子工程中須要依賴jar包還須要添加dependency節點。
父工程的pom文件:


沒有真實依賴,以下圖所示:

子工程的pom文件:

當子工程配置好後,就會有真實依賴,以下圖所示:

5.5.五、父工程中版本號提取

當父工程中定義的jar包愈來愈多,找起來愈來愈麻煩,因此能夠把版本號提取成一個屬性集中管理


子工程的jar包版本不受影響。

5.六、聚合

    聚合通常是一個工程拆分紅多個模塊開發,每一個模塊是一個獨立的工程,可是要是運行時必須把全部模塊聚合到一塊兒纔是一個完整的工程,此時可使用maven的聚合工程。
    例如:電商項目中,包括商品模塊、訂單模塊、用戶模塊等。就能夠對不一樣的模塊單首創建工程,最終在打包時,將不一樣的模塊聚合到一塊兒。
    例如:在真實項目中,同一個項目中的表現層、業務層、持久層,也能夠分層建立不一樣的工程,最後打包運行時,再聚合到一塊兒。對於業務層和持久層,它們能夠在多個工程中被使用,因此通常會將業務層和持久單首創建爲java工程,爲其餘工程依賴。

5.6.一、建立一個聚合工程-不使用骨架

聚合工程的打包方式必須是pom,通常把聚合工程和父工程合併爲一個工程。

5.6.二、建立持久層工程

第一步:在MavenWeb2工程上,點擊new –-> Project…


第二步:點擊 next

/MavenWeb2/pom.xml文件以下圖所示:

5.6.三、建立業務層工程

與持久層工程建立同樣。不在贅述!

5.6.四、建立表現層工程


點擊Next,進行下面的頁面

在MavenController中/MavenWeb2/MavenController/src/main/webapp手動新建WEB-INF目錄和index.jsp文件,並在目錄WEB-INF裏添加web.xml文件,以下圖所示:

聚合以後的MavenWeb工程的pom文件內容以下:

5.6.五、運行MavenWeb聚合工程

命令:tomcat7:run
效果截圖以下:

6、Maven的倉庫管理

6.一、什麼是Maven倉庫?

詳解以下:

    用來統一存儲全部Maven共享構建的位置就是倉庫。
    根據Maven座標定義每一個構建在倉庫中惟一存儲路徑大體爲:groupId/artifactId/version/artifactId-version.packaging
    例如:D:\learn\Java\maven\repository\junit\junit\4.9\junit-4.9.jar

以下圖所示:

6.二、倉庫的分類

詳解以下:

1、本地倉庫
    默認在:~/.m2/repository,若是在用戶配置中有配置,則以用戶配置的地址爲準。
    每一個用戶只有一個本地倉庫。
2、遠程倉庫
    中央倉庫:Maven默認的遠程倉庫,不包含版權資源(即:不包含有版本的jar包)
        http://repo1.maven.org/maven2
    私服:是一種特殊的遠程倉庫,它是架設在局域網內的倉庫。

私服圖解以下圖所示:

6.三、Maven 的私服

6.3.一、安裝Nexus

nexus是用於maven項目中的倉庫的服務器,常常稱其爲:私服。
它是用來存儲和下載一些java依賴文件,經過這些java文件就能夠直接從本地進行一系列用來配置maven中獲取引用jar文件的服務器,而不須要從中央倉庫下載文件。

Nexus是私服的載體,爲全部來自中央倉庫的構建安裝提供本地緩存。
下載網站:http://nexus.sonatype.org/
網站如今變爲:https://www.sonatype.com/
下載地址變爲:https://www.sonatype.com/download-oss-sonatype

因爲官網沒有下載war包的連接了,提供個下載的地方:
連接: https://pan.baidu.com/s/1i6C2sHf    密碼: 2b5t

安裝版本:nexus-2.14.5-02.war

第一步:安裝tomcat,咱們建議:對於不一樣的工程,最好給每個工程配一個專門的tomcat。
第二步:將下載的nexus的war包複製到tomcat下的webapps目錄,以下圖所示:


第三步:啓動tomcat。在 D:\learn\JavaWeb\apache-tomcat\apache-tomcat-9.0.7\bin 目錄中找到 startup.bat,運行它。
nexus將在c盤建立sonatype-work目錄【C:\Users\當前用戶\sonatype-work\nexus】。例如個人:C:\Users\Bruce\sonatype-work\nexus
第四步:nexus的本地目錄,以下圖所示:

第五步:nexus的目錄結構,以下圖所示:

indexer 索引目錄結構,以下圖所示:

storage 存儲目錄結構,以下圖所示:

6.3.二、訪問Nexus

訪問URL: http://localhost:8080/nexus-2.14.5-02/


默認帳號:
用戶名:admin
密碼:admin123

6.3.三、Nexus的倉庫和倉庫組


詳解以下:
倉庫有4種類型:
    `group(倉庫組)`:一組倉庫的集合
    `hosted(宿主)`:配置第三方倉庫(包括公司內部私服) 
    proxy(代理):私服會對中央倉庫進行代理,用戶鏈接私服,私服自動去中央倉庫下載jar包或者插件 
    virtual(虛擬):兼容Maven1 版本的jar或者插件

Nexus的倉庫和倉庫組介紹:
    3rd party:一個策略爲Release的宿主類型倉庫,用來部署沒法從公共倉庫得到的第三方發佈版本構建
    Apache Snapshots:一個策略爲Snapshot的代理倉庫,用來代理Apache Maven倉庫的快照版本構建
    Central:代理Maven中央倉庫
    Central M1 shadow:代理Maven1版本的中央倉庫
    Codehaus Snapshots:一個策略爲Snapshot的代理倉庫,用來代理Codehaus Maven倉庫的快照版本構建
    Releases:一個策略爲Release的宿主類型倉庫,用來部署組織內部的發佈版本構件
    Snapshots:一個策略爲Snapshot的宿主類型倉庫,用來部署組織內部的快照版本構件
    `Public Repositories:該倉庫組將上述全部策略爲Release的倉庫聚合並經過一致的地址提供服務`

注意:下面這個界面的設置:

6.3.四、配置全部構建均從私服下載

在本地倉庫的setting.xml文件中配置以下:
setting.xml文件所在位置爲:D:\learn\Java\maven\settings.xml

  <mirrors>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->

     <mirror>
         <!-- 此處配置全部的構建均從私有倉庫中下載 *表明全部,也能夠寫central -->
         <id>nexus</id>
         <mirrorOf>*</mirrorOf>
         <name>nexus</name>
         <url>http://localhost:8080/nexus-2.14.5-02/content/groups/public/</url>
     </mirror>
  </mirrors>

截圖以下:

6.3.五、部署構建到Nexus--發佈到SNAPSHOT中

第一步:Nexus的訪問權限控制
在本地倉庫的setting.xml文件中配置以下:
setting.xml文件所在位置爲:D:\learn\Java\maven\settings.xml

  <servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     |
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->


    <!-- Another sample, using keys to authenticate.
    <server>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    -->

    <server>
         <id>releases</id>
        <username>admin</username>
        <password>admin123</password>
    </server>
    <server>
        <id>snapshots</id>
        <username>admin</username>
        <password>admin123</password>
    </server>
  </servers>

第二步:配置pom文件
在須要構建的項目中修改pom文件,添加以下配置代碼:

......
    <version>0.0.1-SNAPSHOT</version>
......
    <!-- 部署構建到Nexus -->
    <distributionManagement>
        <repository>
            <id>releases</id>
            <name>Internal Releases</name>
            <url>http://localhost:8080/nexus-2.14.5-02/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Internal Snapshots</name>
            <url>http://localhost:8080/nexus-2.14.5-02/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

第三步:對須要放到Nexus中的項目執行maven的deploy命令
控制檯輸出構建成功截圖:


Nexus Repository Manager OSS 頁面顯示截圖爲:

6.3.六、部署構建到Nexus--發佈到RELEASE中

只在須要構建的項目中修改pom文件的一處地方便可,以下:

......
    <version>0.0.1-RELEASE</version>
......

其餘操做同上。
Nexus Repository Manager OSS 頁面顯示截圖爲:

7、附錄(幾個問題的解決)

7.一、在Nexus Repository Manager OSS 頁面上搜索時,搜索的結果是空白,該如何解決呢?

  問題緣由:咱們在中央倉庫索引庫中沒有咱們要找的文件,也即咱們沒有下載下。
  中央倉庫索引庫的位置:C:\Users\Bruce\sonatype-work\nexus\indexer\central-ctx
  解決辦法:咱們把從網絡上下載好的中央倉庫索引庫文件去覆蓋原來的中央倉庫索引庫文件。

7.二、環境變量:JAVA_HOME最好指定爲jre的路徑,這樣Maven在讀取jar包時纔不會出錯。

  即如今:JAVA_HOME = D:\learn\Java\JRE\jre1.8.0_161
  原來的:JAVA_HOME = D:\learn\Java\JDK\jdk1.8.0_161

  至此,Maven的學習到此結束!!!累屎了o(╥﹏╥)o  ♥曉藝♥

相關文章
相關標籤/搜索