www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]Maven 概述 看完本篇文章后相信你對(duì) Maven 的理解能更進(jìn)一步 常規(guī)項(xiàng)目開發(fā)存在的問題 通常 Web 項(xiàng)目 開發(fā)只會(huì)創(chuàng)建一個(gè)工程,然后所有的 jar 包都會(huì)存放到 WEB-INF/lib 目錄下,如下圖所示: 上面的目錄結(jié)構(gòu)存在以下問題 一個(gè)項(xiàng)目就是一個(gè) web 工程。如果項(xiàng)目


活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


Maven 概述

看完本篇文章后相信你對(duì) Maven 的理解能更進(jìn)一步

常規(guī)項(xiàng)目開發(fā)存在的問題

通常 Web 項(xiàng)目 開發(fā)只會(huì)創(chuàng)建一個(gè)工程,然后所有的 jar 包都會(huì)存放到 WEB-INF/lib 目錄下,如下圖所示:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


上面的目錄結(jié)構(gòu)存在以下問題

  • 一個(gè)項(xiàng)目就是一個(gè) web 工程。如果項(xiàng)目比較龐大,那么利用包名 package 來劃分模塊,顯然容易造成混淆而且不利于分工合作;
  • 項(xiàng)目中需要的 jar 包必須手動(dòng)復(fù)制,粘貼到 WEB-INF/lib 目錄下。這會(huì)導(dǎo)致每創(chuàng)建一個(gè)新的工程就需要將 jar 包重復(fù)復(fù)制到 lib 目錄下,從而造成工作區(qū)存在大量重復(fù)的文件;
  • jar 需要我們手動(dòng)去官網(wǎng)上或者其他途徑下載;
  • 一個(gè) jar 包依賴的其他 jar 包,需要自己手動(dòng)加入到項(xiàng)目中,而且很有可能我們漏掉了某個(gè)依賴關(guān)系,導(dǎo)致項(xiàng)目運(yùn)行報(bào)錯(cuò)。

那么如何解決這些問題呢?我們的主角 Maven 應(yīng)運(yùn)而生了。

什么是 Maven

Maven 讀音是 [?mev?n],也就是霉文,而不是讀馬文。它是一個(gè)項(xiàng)目管理和綜合工具,Maven 使用標(biāo)準(zhǔn)的目錄結(jié)構(gòu)和默認(rèn)構(gòu)建生命周期。提供了開發(fā)人員構(gòu)建一個(gè)完整的生命周期框架,開發(fā)團(tuán)隊(duì)可以自動(dòng)完成該項(xiàng)目的基礎(chǔ)設(shè)施建設(shè)。相信如果對(duì) Maven 沒有任何了解的,看了這段話等于沒看,不過沒關(guān)系,后面我們將會(huì)逐漸揭開 Maven 的神秘面紗。什么是 Maven,你只需要知道這玩意能簡化和標(biāo)準(zhǔn)化項(xiàng)目建設(shè)過程。

Maven 的歷史

Maven的 最初設(shè)計(jì),以簡化Jakarta Turbine 項(xiàng)目的建設(shè)進(jìn)程。有幾個(gè)項(xiàng)目,每個(gè)項(xiàng)目包含了稍微不同的 Ant 構(gòu)建文件。JAR 中檢查到 CVS。Apache 組織開發(fā)的 Maven 可以建立多個(gè)項(xiàng)目,發(fā)布項(xiàng)目信息,項(xiàng)目部署。

Maven 的目標(biāo)

Maven主要目標(biāo)是提供開發(fā)人員

  • 項(xiàng)目是可重復(fù)使用,易維護(hù),更容易理解的一個(gè)綜合模型。
  • 插件或交互的工具,這種聲明性的模式。

Maven 項(xiàng)目的結(jié)構(gòu)和內(nèi)容是在一個(gè) XML 文件中聲明,pom.xml 的項(xiàng)目對(duì)象模型(POM),這是整個(gè) Maven 系統(tǒng)的基本單元。

Maven 的理念是 「約定優(yōu)于配置?。?!」

開發(fā)人員不需要?jiǎng)?chuàng)建構(gòu)建過程本身,不必知道提到的每一個(gè)配置的詳細(xì)信息。Maven 提供了合理的默認(rèn)行為的項(xiàng)目。創(chuàng)建一個(gè) Maven 項(xiàng)目時(shí),Maven 創(chuàng)建默認(rèn)的項(xiàng)目結(jié)構(gòu)。開發(fā)者只需要把相應(yīng)的文件和她需要在 pom.xml 中定義即可。

Maven 的安裝和配置

Maven 下載

官網(wǎng)下載地址:http://maven.apache.org/download.cgi

配置 Maven 環(huán)境變量

將下載的 maven 壓縮包解壓到電腦的某個(gè)盤符,我這里是 D:\JavaTools\apache-maven-3.3.9

「右鍵---計(jì)算機(jī)屬性----高級(jí)系統(tǒng)設(shè)置---高級(jí)---環(huán)境變量---系統(tǒng)變量----新建」

變量名:MAVEN_HOME

變量值:D:\JavaTools\apache-maven-3.3.9

這個(gè)值是 maven 壓縮包解壓的位置

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


「將 MAVEN_HOME 添加到 path 目錄下」

選擇 path---編輯---新建---將 %MAVEN_HOME%\bin  添加進(jìn)去,然后點(diǎn)擊確定就可以了

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


查看環(huán)境變量是否配置成功

打開命令提示符,快捷鍵 windows + R.輸入 mvn -v

如果出現(xiàn)如下 maven 的版本信息,那么就配置成功

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


在 eclipse 中集成 Maven 插件

在 eclipse 指定 Maven 插件的位置 : Window->Preferences->Maven->Installations

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

指定 conf/settings.xml 的位置,進(jìn)而指定 Maven 本地倉庫的位置

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

修改 settings.xml 如下標(biāo)簽的位置即可: 自定義路徑

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


Maven 工程目錄介紹

上面我們配置并安裝好了 Maven,那么現(xiàn)在我們就來介紹一下如何用 eclipse 創(chuàng)建一個(gè) Maven 工程,然后介紹 Maven 工程的目錄結(jié)構(gòu)。

eclipse 創(chuàng)建 Maven 工程

「第一步:File-->New--->Maven Project」

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


「第二步:勾上 Create a simple project ,然后點(diǎn)擊 next」

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


「第三步:填寫 Group Id 和 Artifact Id」

groupidartifactId 被統(tǒng)稱為坐標(biāo) 是為了保證項(xiàng)目唯一性而提出的,如果你要把你項(xiàng)目弄到 maven 本地倉庫去,你想要找到你的項(xiàng)目就必須根據(jù)這兩個(gè) id 去查找。

groupId 一般分為多個(gè)段,這里只說兩段

第一段為域,第二段為公司名稱。域又分為org、com、cn等等許多,其中org為非營利組織,com為商業(yè)組織。舉個(gè)apache公司的tomcat項(xiàng)目例子:這個(gè)項(xiàng)目的groupId是org.apache,它的域是org(因?yàn)閠omcat是非營利項(xiàng)目),公司名稱是apache,artigactId是tomcat。

ArtifactID 就是項(xiàng)目的唯一的標(biāo)識(shí)符,實(shí)際對(duì)應(yīng)項(xiàng)目的名稱,就是項(xiàng)目根目錄的名稱。比如我創(chuàng)建一個(gè)項(xiàng)目,我一般會(huì)將 groupId 設(shè)置為 com.ys,com 表示域,ys 是我個(gè)人姓名縮寫,「Artifact Id」設(shè)置為 hellomaven,表示你這個(gè)項(xiàng)目的名稱是 hellomaven,依照這個(gè)設(shè)置,你的包結(jié)構(gòu)最好是 com.ys.hellomaven 打頭的,如果有個(gè)StudentDao,它的全路徑就是 com.ys.hellomaven.dao.StudentDao  活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

Maven Java 工程目錄結(jié)構(gòu)

我們根據(jù)上面的步驟,創(chuàng)建出如下的 maven 工程:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


對(duì)每個(gè)目錄結(jié)構(gòu)的解析如下:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

為什么 maven 工程的目錄結(jié)構(gòu)要這樣呢?

  • Maven 要負(fù)責(zé)項(xiàng)目的自動(dòng)化構(gòu)建,以編譯為例,Maven 要想自動(dòng)進(jìn)行編譯,那么它必須知道 Java 的源文件保存在哪里,這樣約定之后,不用我們手動(dòng)指定位置,Maven 能知道位置,從而幫我們完成自動(dòng)編譯。

  • 遵循 約定>>>配置>>>編碼。即能進(jìn)行配置的不要去編碼指定,能事先約定規(guī)則的不要去進(jìn)行配置。這樣既減輕了勞動(dòng)力,也能防止出錯(cuò)。

「pom.xml 文件」

Project Object Model 項(xiàng)目對(duì)象模型,Maven 的核心配置文件,pom.xml,與構(gòu)建過程相關(guān)的一切設(shè)置都在這個(gè)文件中進(jìn)行配置。

這個(gè)文件非常重要,我們后面會(huì)詳細(xì)講解。

常用的 Maven 命令

創(chuàng)建 Maven 工程

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


在 src/main/java 新建包 com.ys.maven,然后在這個(gè)包中創(chuàng)建類 HelloMaven.java

package com.ys.maven;
 
public class HelloMaven {
     
    //傳入一個(gè)字符串并返回
    public String Hello(String name){
         
        return name;
    }
}

在 src/test/java 新建包 com.ys.maven,然后在這個(gè)包中創(chuàng)建類 HelloTest.java

package com.ys.maven;
 
import junit.framework.Assert;
import org.junit.Test;
 
public class HelloTest {
     
    @Test
    public void testHello(){
        HelloMaven he = new HelloMaven();
        String name = he.Hello("Tom");
        //判斷 Hello 傳入的參數(shù)是否是 "maven"
        Assert.assertEquals("maven", name);
    }
 
}

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"
>

      
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ys</groupId>
  <artifactId>hellomaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
   
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.0</version>
        <scope>test</scope>
    </dependency>
  </dependencies>
</project>

為什么要這樣寫,我們后面會(huì)詳細(xì)講解。

Maven 的常用命令

mvn compile 編譯,將Java 源程序編譯成 class 字節(jié)碼文件。
mvn test 測(cè)試,并生成測(cè)試報(bào)告
mvn clean 將以前編譯得到的舊的 class 字節(jié)碼文件刪除
mvn pakage 打包,動(dòng)態(tài) web工程打 war包,Java工程打 jar 包。
mvn install 將項(xiàng)目生成 jar 包放在倉庫中,以便別的模塊調(diào)用

compile:將Java 源程序編譯成 class 字節(jié)碼文件。

第一步:選擇 pom.xml 文件,右鍵--->Run As ---->2 Maven build...活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

第二步:在第一步執(zhí)行完后彈出來的對(duì)話框中,輸入 compile,然后點(diǎn)擊 Run 按鈕

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第三步:查看控制臺(tái)活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

第四步:在 target 目錄下,我們會(huì)發(fā)現(xiàn)編譯生成的 class 文件

test:測(cè)試,并生成測(cè)試報(bào)告

  • 第一步:選擇 pom.xml 文件,右鍵--->Run As ---->2 Maven build...,然后在彈出框中輸入 test,或者選擇 pom.xml 文件,右鍵--->Run As------>6 Maven test

  • 第二步:查看控制臺(tái),分析測(cè)試程序,我們傳入的參數(shù)是Tom,而我們希望的是maven,很顯然是不相等的,那么測(cè)試失敗  活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

如果測(cè)試類 HelloTest.java改為如下:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


重新執(zhí)行 mvn test 命令,控制臺(tái)如下: 活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)生成的測(cè)試報(bào)告可以在如下目錄查看:target/surefire-reports

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


mvn clean 將以前編譯得到的舊的 class 字節(jié)碼文件刪除

  • 第一步:選擇 pom.xml 文件,右鍵--->Run As ---->2 Maven build...,然后在彈出框中輸入 clean

或者選擇 pom.xml 文件,右鍵--->Run As------>3 Maven clean,如下圖

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

  • 第二步:查看控制臺(tái) 活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

  • 第三步:發(fā)現(xiàn) mvn compile 編譯好的文件這時(shí)已經(jīng)清除了

mvn pakage 打包,動(dòng)態(tài) web工程打 war包,Java工程打 jar 包。

  • 第一步:選擇 pom.xml 文件,右鍵--->Run As ---->2 Maven build...,然后在彈出框中輸入 package
活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

  • 第二步:查看控制臺(tái)活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

  • 第三步:進(jìn)入到 target 目錄,會(huì)發(fā)現(xiàn)打出來的 jar 包

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


mvn install 將項(xiàng)目生成 jar 包放在倉庫中,以便別的模塊調(diào)用

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


Maven 坐標(biāo)的概念和依賴管理

我們知道 maven 能幫我們管理jar包,那么它是怎么管理的呢?我們下面就來講解一下

什么是坐標(biāo)

「數(shù)學(xué)中的坐標(biāo)」

在平面上,使用 X 、Y 兩個(gè)向量可以唯一的定位平面中的任何一個(gè)點(diǎn)

在空間中,使用 X、Y、Z 三個(gè)向量可以唯一的定位空間中的任意一個(gè)點(diǎn)

「Maven 中的坐標(biāo)」

俗稱 gav:使用下面三個(gè)向量子倉庫中唯一定位一個(gè) Maven 工程

在項(xiàng)目中的 pom.xml 文件中,我們可以看到下面 gav 的定義

  • groupid:公司或組織域名倒序 : com.ys.maven
  • artifactid:模塊名,也是實(shí)際項(xiàng)目的名稱: Maven_05
  • version:當(dāng)前項(xiàng)目的版本: 0.0.1-SNAPSHOT
活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


「Maven 坐標(biāo)和倉庫,jar 包的關(guān)系」

什么是倉庫,后面我們會(huì)詳細(xì)講解,現(xiàn)在你只需要知道是 Maven 用來存放 jar 包的地方。

那么依照上面定義的 gav,我們執(zhí)行 mvn -install 命令,會(huì)出現(xiàn)什么情況呢?

首先進(jìn)入到我們上面講過的 settings.xml 文件配置的倉庫目錄。

將我們上面配置的 gav 向量組合起來就是目錄:

com/ys/maven/Maven_05/0.0.1-SNAPSHOT/Maven_05-0.0.1-SNAPSHOT.jar

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


其次,我們觀察打出來的 jar 包:Maven_05-0.0.1-SNAPSHOT.jar,也就是 artifactid-version.jar

Maven 依賴

什么是依賴?相信有過一定開發(fā)經(jīng)驗(yàn)的人知道,每當(dāng)我們需要使用某個(gè)框架時(shí),比如 SpringMVC,那么我們需要導(dǎo)入相應(yīng)的 jar 包,但是手動(dòng)導(dǎo)入包的時(shí)候,往往會(huì)漏掉幾個(gè) jar 包,那么在使用該框架的時(shí)候系統(tǒng)就會(huì)報(bào)錯(cuò)。那么我們就說導(dǎo)入的包與未導(dǎo)入的包存在依賴關(guān)系。而使用 Maven,我們只需要在 pom.xml 文件中進(jìn)行相應(yīng)的配置,它就會(huì)幫助我們自動(dòng)管理 jar 包之間的依賴關(guān)系。那么它是怎么管理的呢,接下來我們會(huì)詳細(xì)講解。

依賴的詳細(xì)配置

我們以 Junit 為例,在 pom.xml 文件中進(jìn)行詳細(xì)而完整的配置。

<project>     
    <dependencies>
        <dependency>
            <groupId>junit</groupId>     
            <artifactId>junit</artifactId>     
            <version>3.8.1</version>
            <type>...</type>
            <scope>...</scope>
            <optional>...</optional>
            <exclusions>     
                <exclusion>     
                  <groupId>...</groupId>     
                  <artifactId>...</artifactId>     
                </exclusion>
          </exclusions>     
        </dependency>        
      </dependencies>     
</project>
  • dependencies:一個(gè) pom.xml 文件中只能存在一個(gè)這樣的標(biāo)簽。用來管理依賴的總標(biāo)簽。

  • dependency: 包含在 dependencies 標(biāo)簽中,可以有無數(shù)個(gè),每一個(gè)表示一個(gè)依賴

  • groupId、artifactId 和 version:依賴的基本坐標(biāo),對(duì)于任何一個(gè)依賴來說,基本坐標(biāo)是最重要的,Maven根 據(jù)坐標(biāo)才能找到需要的依賴。

  • type:依賴的類型,對(duì)應(yīng)于項(xiàng)目坐標(biāo)定義的 packaging。大部分情況下,該元素不必聲明,其默認(rèn)值是 jar。

  • scope:依賴的范圍,默認(rèn)值是 compile。后面會(huì)進(jìn)行詳解。

  • optional:標(biāo)記依賴是否可選。

  • exclusions:用來排除傳遞性依賴,后面會(huì)進(jìn)行詳細(xì)介紹。

依賴的范圍 scope

先放一張圖

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


一般情況下,我們對(duì)前面三個(gè)依賴用的比較多。下面的主程序表示 maven 目錄結(jié)構(gòu) src/main/java.測(cè)試程序目錄結(jié)構(gòu)為:src/test/java

「compile 范圍依賴」

對(duì)主程序是否有效:有效

對(duì)測(cè)試程序是否有效:有效

是否參與打包:參與

是否參與部署:參與

典型例子:log4j

「test 范圍依賴」

對(duì)主程序是否有效:無效

對(duì)測(cè)試程序是否有效:有效

是否參與打包:不參與

是否參與部署:不參與

典型例子:Junit

「provided 范圍依賴」

對(duì)主程序是否有效:有效

對(duì)測(cè)試程序是否有效:有效

是否參與打包:不參與

是否參與部署:不參與

典型例子:servlet-api.jar,一般在發(fā)布到 服務(wù)器中,比如 tomcat,服務(wù)器會(huì)自帶 servlet-api.jar 包,所以provided 范圍依賴只在編譯測(cè)試有效。

「runtime 范圍依賴」:在測(cè)試、運(yùn)行的時(shí)候依賴,在編譯的時(shí)候不依賴。例如:JDBC 驅(qū)動(dòng),項(xiàng)目代碼只需要 jdk 提供的 jdbc 接口,只有在執(zhí)行測(cè)試和運(yùn)行項(xiàng)目的時(shí)候才需要實(shí)現(xiàn) jdbc 的功能。

接下來我們舉幾個(gè)例子在工程中實(shí)際去理解:

「test 依賴和 compile 依賴的區(qū)別:」

首先我們?cè)?pom.xml 文件中配置,Junit 的 test 依賴

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


我們?cè)谥鞒绦蛑腥?dǎo)入 Junit 的包,然后進(jìn)行 mvn -compile 編譯,很明顯,test 范圍的在主程序中無效,故編譯會(huì)報(bào)錯(cuò)。

我們?cè)?src/main/java 包下新建 MavenTest.java,并導(dǎo)入 Junit 包活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

然后執(zhí)行 mvn -compile 操作,如下圖報(bào)錯(cuò)信息:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


我們將 Junit 的依賴范圍改為 compile,然后執(zhí)行 mvn -compile 活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

發(fā)現(xiàn) mvn -compile 沒有報(bào)錯(cuò)了?! ?img data-w="532" style="border-radius: 6px;display: block;margin: 20px auto;object-fit: contain;box-shadow: rgb(153, 153, 153) 2px 4px 7px;" src="/images/21ic_nopic.gif" data-src="a934Di8GM0XXj5AUhGfaVrtfD6auHlx2w17Hmp1HVCV3y38QrDNUOZtrtou06qYznVx4mUQTXMVao9QGEahWoBQA6ipw5feYsOE" class="delay_img" alt="活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)" >

依賴的傳遞

比如我們創(chuàng)建三個(gè) Maven 工程,maven-first,maven-second 以及 maven-third,而 third 依賴于 second,second 又依賴于 first,那么我們說 second 是 third 的第一直接依賴,first 是 second 的第二直接依賴。而 first 是 third 的間接依賴。

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


依賴之間的傳遞如下圖:「第一列表示第一直接依賴,第一行表示第二直接依賴」

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


總結(jié)

當(dāng)?shù)诙蕾嚨姆秶?compile 的時(shí)候,傳遞性依賴的范圍與第一直接依賴的范圍一致。

當(dāng)?shù)诙苯右蕾嚨姆秶?test的時(shí)候,依賴不會(huì)得以傳遞。

當(dāng)?shù)诙蕾嚨姆秶?provided 的時(shí)候,只傳遞第一直接依賴范圍也為provided 的依賴,且傳遞性依賴的范圍同樣為 provided;

當(dāng)?shù)诙苯右蕾嚨姆秶?runtime 的時(shí)候,傳遞性依賴的范圍與第一直接依賴的范圍一致,但compile例外,此時(shí)傳遞的依賴范圍為 runtime;

我們這里舉個(gè)例子來看:

第二依賴范圍是 test

Maven_first 的pom.xml 文件如下:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

然后 Maven_second 依賴 Maven_fisrt,Maven_third 依賴 Maven-second,其pom.xml 文件如下

Maven_second的 pom.xml

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

Maven_third 的 pom.xml

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


我們發(fā)現(xiàn)在 Maven_third 和 Maven_second 都沒有 Maven_first 引入的 Junit 包,正好符合上面總結(jié)的第二點(diǎn):當(dāng)?shù)诙苯右蕾嚨姆秶莟est的時(shí)候,依賴不會(huì)得以傳遞。

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第二依賴范圍是 compile

如果我們將 Maven_first 的Junit 改為 compile,那么將會(huì)符合上面總結(jié)的第一點(diǎn):當(dāng)?shù)诙蕾嚨姆秶莄ompile的時(shí)候,傳遞性依賴的范圍與第一直接依賴的范圍一致。

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


依賴的排除

如果我們?cè)诋?dāng)前工程中引入了一個(gè)依賴是 A,而 A 又依賴了 B,那么 Maven 會(huì)自動(dòng)將 A 依賴的 B 引入當(dāng)前工程,但是個(gè)別情況下 B 有可能是一個(gè)不穩(wěn)定版,或?qū)Ξ?dāng)前工程有不良影響。這時(shí)我們可以在引入 A 的時(shí)候?qū)?B 排除。

比如:我們?cè)贛aven_first 中添加 spring-core,maven 會(huì)自動(dòng)將 commons-logging添加進(jìn)來,那么由于 Maven_second 是依賴 Maven_first  的,那么 Maven_second  中將存在 spring-core(自帶了commons-logging),這時(shí)候我們不想要 commons-logging,那該怎么辦呢?我們上面第二大點(diǎn)提到了:

exclusions:用來排除傳遞性依賴

Maven_first 的 pom.xml 文件

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


由于 Maven_second 依賴 Maven_second,故 Maven_second 存在 spring-core 包

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


如何排除呢?我們?cè)?Maven_second 的 pom.xml 文件中添加如下代碼:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


再次查看工程:Maven_second 的 commons-logging 已經(jīng)移除了

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


依賴的沖突

在 maven 中存在兩種沖突方式:一種是跨 pom 文件的沖突,一致是同一個(gè) pom 文件中的沖突。

「跨 pom 文件,路徑最短者優(yōu)先」。

比如我們?cè)?Maven_first 中的 Junit 是4.9版本的,Maven_second 中的 Junit 是4.8版本的,那么Maven_third 中的 Junit 將會(huì)是那個(gè)版本呢?

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


由上圖我們可以看出,由于 Maven_second 是 Maven_third 的直接依賴,明顯相比于 Maven_first 路徑要短,所以 Maven_third 的 Junit 版本與 Maven_second 保持一致

「同一個(gè)pom.xml 文件,先申明者優(yōu)先」

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


「看 Maven_second」

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


可選依賴

Optional 標(biāo)簽標(biāo)示該依賴是否可選,默認(rèn)是 false??梢岳斫鉃椋绻麨?true,則表示該依賴不會(huì)傳遞下去,如果為false,則會(huì)傳遞下去。

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


我們是在 Maven_second 的 pom 文件中設(shè)定 Junit 不可傳遞,那么Maven_third 工程中將不會(huì)有來自 Maven_second 的 Junit 的傳遞。

Maven 生命周期

什么是生命周期

Maven 強(qiáng)大的原因是有一個(gè)十分完善的生命周期,生命周期可以理解為項(xiàng)目構(gòu)建步驟的集合,它定義了各個(gè)構(gòu)建環(huán)節(jié)的執(zhí)行順序,有了這個(gè)順序,Maven 就可以自動(dòng)化的執(zhí)行構(gòu)建命令。

Maven 的核心程序中定義了抽象的生命周期,生命周期中各個(gè)階段的具體任務(wù)是由插件來完成的。有三套相互獨(dú)立的生命周期,各個(gè)構(gòu)建環(huán)節(jié)執(zhí)行順序不能打亂,必須按照既定的正確順序來執(zhí)行。

  • 「Clean Lifecycle : 在進(jìn)行真正的構(gòu)建之前進(jìn)行一些清理工作」
  • 「Default Lifecycle:構(gòu)建的核心部分,編譯、測(cè)試、打包、安裝、部署等等」。
  • 「Site Lifecycle:生成項(xiàng)目報(bào)告,站點(diǎn),發(fā)布站點(diǎn)」。

這三個(gè)都是相互獨(dú)立的。你可以僅僅調(diào)用 clean 來清理工作目錄,僅僅調(diào)用 site 來生成站點(diǎn)。當(dāng)然,也可以直接運(yùn)行 mvn claen install site 運(yùn)行所有這三套生命周期。下面我們分別來談?wù)勥@三個(gè)生命周期。

Clean Lifecycle

pre-clean 執(zhí)行一些需要在clean之前完成的工作
clean 移除所有上一次構(gòu)建生成的文件
post-clean 執(zhí)行一些需要在clean之后立刻完成的工作

我們前面講的執(zhí)行命令 mvn -clean,也就等同于 Clean 生命周期中的第一個(gè)階段 mvn pre-clean clean。注意有 Clean 聲明周期,而這個(gè)聲明周期中又有 clean 階段。

只要執(zhí)行后面的命令,那么前面的命令都會(huì)執(zhí)行,不需要再重新去輸入命令

Default Lifecycle

validate 
generate-sources 
process-sources 
generate-resources 
process-resources 復(fù)制并處理資源文件,至目標(biāo)目錄,準(zhǔn)備打包。 
compile 編譯項(xiàng)目的源代碼。 
process-classes 
generate-test-sources 
process-test-sources 
generate-test-resources 
process-test-resources 復(fù)制并處理資源文件,至目標(biāo)測(cè)試目錄。 
test-compile 編譯測(cè)試源代碼。 
process-test-classes 
test 使用合適的單元測(cè)試框架運(yùn)行測(cè)試。這些測(cè)試代碼不會(huì)被打包或部署。 
prepare-package 
package 接受編譯好的代碼,打包成可發(fā)布的格式,如 JAR 。 
pre-integration-test 
integration-test 
post-integration-test 
verify 
install 將包安裝至本地倉庫,以讓其它項(xiàng)目依賴。 
deploy 將最終的包復(fù)制到遠(yuǎn)程的倉庫,以讓其它開發(fā)人員與項(xiàng)目共享。

這里我們強(qiáng)調(diào)一下:「在maven中,只要在同一個(gè)生命周期,你執(zhí)行后面的階段,那么前面的階段也會(huì)被執(zhí)行,而且不需要額外去輸入前面的階段」。

我們舉個(gè)例子:執(zhí)行 mven compile 命令,根據(jù)上面的聲明周期,它會(huì)默認(rèn)執(zhí)行前面五個(gè)個(gè)步驟也就是

validate
generate-sources
process-sources
generate-resources
process-resources 復(fù)制并處理資源文件,至目標(biāo)目錄,準(zhǔn)備打包。
compile 編譯項(xiàng)目的源代碼。

我們?cè)?eclipse 中執(zhí)行 mvn compile 命令

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


看到紅色框的兩部分,第一個(gè) maven-compiler-plugin:2.6:resource 就是用來執(zhí)行前面幾個(gè)步驟的插件,第二個(gè)插件 maven-compiler-plugin:3.1:compile 則是用來執(zhí)行 mvn compile 的插件。這里我們提一下,mvn 的各個(gè)生命周期步驟都是依賴插件來完成的,后面我們會(huì)詳細(xì)講解 maven 插件。

pre-site 執(zhí)行一些需要在生成站點(diǎn)文檔之前完成的工作
site 生成項(xiàng)目的站點(diǎn)文檔
post-site 執(zhí)行一些需要在生成站點(diǎn)文檔之后完成的工作,并且為部署做準(zhǔn)備
site-deploy 將生成的站點(diǎn)文檔部署到特定的服務(wù)器上

這里經(jīng)常用到的是 site 階段和 site-deploy 階段,用來生成和發(fā)布 maven 站點(diǎn),這是 Maven 比較強(qiáng)大的功能,文檔及統(tǒng)計(jì)數(shù)據(jù)自動(dòng)生成。由于現(xiàn)在的系統(tǒng)會(huì)有專門工具來生成文檔或報(bào)表。所以這個(gè)功能也是比較雞肋吧,不夠簡潔和美觀,用的不太多。

Maven 插件原理

什么是 Maven 插件

上面我們講了 Maven 的生命周期,我們知道 Maven 的核心是生命周期,生命周期指定了 Maven 命令執(zhí)行的流程順序。但是真正實(shí)現(xiàn)流程的工程是由插件來完成的。

我們也可以說 Maven 是一個(gè)執(zhí)行插件的框架,每一個(gè)任務(wù)實(shí)際上都是有插件來完成。進(jìn)一步說每個(gè)任務(wù)對(duì)應(yīng)了一個(gè)插件目標(biāo)(goal),每個(gè)插件會(huì)有一個(gè)或者多個(gè)目標(biāo),例如 maven-compiler-plugin 的 compile 目標(biāo)用來編譯位于 src/main/java/ 目錄下的主源碼,testCompile 目標(biāo)用來編譯位于src/test/java/目錄下的測(cè)試源碼。

配置編譯插件

一般我們創(chuàng)建一個(gè) Maven 工程,就算指定了 JDK 的版本,但是你執(zhí)行 update project 操作,一般 Maven 工程會(huì)自動(dòng)恢復(fù)到默認(rèn)的 JDK 版本,有可能是1.4,有可能是1.5(和 Maven 版本有關(guān))。

那么我們?nèi)绾沃付ㄆ?JDK 版本呢?在 pom.xml 中添加如下代碼:

<build>
    <plugins>
        <!-- 編譯插件,指定 JDK 的版本為1.7 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

下面我們來添加一個(gè) tomcat 插件,首先我們要知道如何創(chuàng)建 Maven Web 工程。

創(chuàng)建 Maven Web 工程

第一步:New maven project,注意打包方式為 war

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第二步:右擊項(xiàng)目名,選擇 properties,選擇Project Facets

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第三步:將 Dynamic Web Module 取消,點(diǎn)擊 Apply

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第四部:將 Dynamic Web Module 重新勾選,點(diǎn)擊 下方生成的超鏈接

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第五步:點(diǎn)擊超鏈接,修改目錄結(jié)構(gòu),然后點(diǎn)擊 OK,創(chuàng)建 Maven Web 工程完成

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


創(chuàng)建的 Web 工程目錄結(jié)構(gòu)如下:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


添加 tomcat 插件

我們?cè)谏厦鎰?chuàng)建的 web 工程,可以輸入  tomcat:run 來使用默認(rèn)的 tomcat 插件去啟動(dòng) web 工程,但是默認(rèn)的插件版本有點(diǎn)低,我們可以手動(dòng)添加插件。

<build>
    <plugins>
        <!--配置tomcat 插件  -->
    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <configuration>
            <port>8080</port><!--端口號(hào)  -->
            <path>/</path>
        </configuration>
    </plugin>
</plugins>

執(zhí)行命令是輸入:tomcat7:run

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


Maven 繼承和聚合

繼承

有三個(gè) Maven 工程,每個(gè)工程都依賴某個(gè) jar 包,比如 Junit,由于 test 范圍的依賴不能傳遞,它必然會(huì)分散在每個(gè)工程中,而且每個(gè)工程的jar 包版本可能不一致。那么如何管理各個(gè)工程中對(duì)于某個(gè) jar 包的版本呢?

「解決辦法:」

將那個(gè) jar 包版本統(tǒng)一提取到 工程中,在子工程中聲明依賴時(shí)不指定版本,以父工程中統(tǒng)一設(shè)定的為準(zhǔn),同時(shí)也便于修改。

操作步驟:

創(chuàng)建父工程

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


在子工程中聲明對(duì)父工程的引用

<!--子工程中聲明對(duì)父工程的引用  -->
<parent>
  <groupId>com.ys.maven</groupId>
  <artifactId>Parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <!-- 以當(dāng)前工程文件為基準(zhǔn)的父工程 pom.xml文件的相對(duì)路徑(可以不配置) -->
  <relativePath>../Parent/pom.xml</relativePath>
</parent>

將子工程的坐標(biāo)中與父工程坐標(biāo)重復(fù)的內(nèi)容刪除(不刪除也可以,為了簡潔)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</dependencyManagement>

dependencyManagement標(biāo)簽管理的依賴,其實(shí)沒有真正依賴,它只是管理依賴的版本。

在子工程中刪除 Junit 的版本號(hào)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)以后要更改版本號(hào),我們只需要更改父工程中的版本號(hào)即可?。?!

父工程通過 properties 統(tǒng)一管理版本號(hào)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


我們可以通過<properties></properties>自定義標(biāo)簽,然后在標(biāo)簽里面填寫常量,這種方法不僅可以用來管理版本號(hào),還可以用來管理比如設(shè)置某種編碼等等。

聚合

需求場景:

在真實(shí)項(xiàng)目中,一個(gè)項(xiàng)目有表現(xiàn)層、業(yè)務(wù)層、持久層等。我們?cè)谟肕aven 管理項(xiàng)目的時(shí)候,通常為創(chuàng)建多個(gè) Maven 工程,也就是一個(gè)項(xiàng)目的多個(gè)模塊。但是這樣分成多個(gè)模塊了,當(dāng)我們進(jìn)行項(xiàng)目打包發(fā)布的時(shí)候,那么要每一個(gè)模塊都執(zhí)行打包操作嗎?這種重復(fù)的操作我們?cè)趺床拍鼙苊饽兀?/p>

解決辦法:

創(chuàng)建一個(gè)聚合工程,將其他的各個(gè)模塊都由這個(gè)聚合工程來管理,那么我們?cè)谶M(jìn)行項(xiàng)目發(fā)布的時(shí)候,只需要打包這個(gè)聚合工程就可以了。

第一步:創(chuàng)建聚合工程(注意聚合工程的打包方式也必須為 pom,通常由 上面所講的父工程來充當(dāng)聚合工程)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第二步:創(chuàng)建子工程:業(yè)務(wù)層

選擇 Maven Module

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


填寫子工程模塊名,打包方式選擇 jar(子工程除了 web 層我們打包方式選擇 war ,其余的都選擇 jar)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)


第三步:創(chuàng)建子工程:表現(xiàn)層和持久層

創(chuàng)建步驟和前面一樣,注意表現(xiàn)層打包方式我們要選擇 war,因?yàn)橐l(fā)布到 tomcat 容器運(yùn)行。

第四步:在聚合工程中添加子工程的引用

<modules>
  <module>Service</module>
  <module>Controller</module>
  <module>Mapper</module>
</modules>

注意:這里雖然各個(gè)模塊有依賴關(guān)系,但是 可以不讓依賴順序添加,maven會(huì)自動(dòng)識(shí)別依賴關(guān)系進(jìn)行編譯打包。

這里總的聚合工程隨便哪個(gè)工程都可以,但是通常用 Parent 工程來完成。


文章經(jīng)由作者原創(chuàng)授權(quán) https://www.cnblogs.com/ysocean/


特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

長按訂閱更多精彩▼

活久見!64 張圖帶你 Maven 實(shí)戰(zhàn)通關(guān)

如有收獲,點(diǎn)個(gè)在看,誠摯感謝


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場,如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉