溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Maven的插件以及生命周期的介紹

發(fā)布時(shí)間:2021-09-04 10:30:46 來源:億速云 閱讀:157 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“Maven的插件以及生命周期的介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Maven的插件以及生命周期的介紹”吧!

Maven:是一個(gè)項(xiàng)目管理和整合工具(類似python中的pi 不過更加強(qiáng)大而已)。Maven 為開發(fā)者提供了一套完整的構(gòu)建生命周期框架。開發(fā)團(tuán)隊(duì)幾乎不用花多少時(shí)間就能夠自動(dòng)完成工程的基礎(chǔ)構(gòu)建配置,因?yàn)?Maven 使用了一個(gè)標(biāo)準(zhǔn)的目錄結(jié)構(gòu)和一個(gè)默認(rèn)的構(gòu)建生命周期。這里切記 約定大于配置。簡(jiǎn)而言之:

Maven 的主要目的是為開發(fā)者提供

  • 一個(gè)可復(fù)用、可維護(hù)、更易理解的工程綜合模型

  • 與這個(gè)模型交互的插件或者工具

  • Maven的倉(cāng)庫(kù)管理、依賴管理、繼承和聚合等特性為項(xiàng)目的構(gòu)建提供了一整套完善的解決方案

maven的構(gòu)建生命周期,只是一個(gè)抽象規(guī)范流程。周期內(nèi)的每個(gè)階段的具體執(zhí)行,是在插件里來實(shí)現(xiàn)。

Maven的插件以及生命周期的介紹

Maven 聲明周期預(yù)設(shè)定義:

運(yùn)行任何一個(gè)階段,都會(huì)從其所在生命周期的第一個(gè)階段開始,順序執(zhí)行到指定的階段 

Maven的插件以及生命周期的介紹

Maven 插件

插件plugin是綁定到生命周期,承擔(dān)實(shí)際功能的組件。mvn運(yùn)行時(shí),自動(dòng)關(guān)聯(lián)插件來運(yùn)行??梢院?jiǎn)單的理解為一個(gè)插件就是一個(gè)package,里面有細(xì)節(jié)的.class文件,.class文件里又有具體的操作函數(shù)。 

上面描述了我們對(duì)Maven的一些使用方式,下面我們進(jìn)行一些思考:

1、本地倉(cāng)庫(kù)?Maven到底有哪些倉(cāng)庫(kù)?它們什么關(guān)系?

Maven倉(cāng)庫(kù):

Maven的插件以及生命周期的介紹

本地倉(cāng)庫(kù)路徑配置:

Maven的插件以及生命周期的介紹

你要jar包,不可能每次都要聯(lián)網(wǎng)去下載吧,多費(fèi)勁,所以本地倉(cāng)庫(kù)就是相當(dāng)于加了一層jar包緩存,先到這里來查。如果這里查不到,那么就去私服上找,如果私服也找不到,那么去中央倉(cāng)庫(kù)去找,找到j(luò)ar后,會(huì)把jar的信息同步到私服和本地倉(cāng)庫(kù)中。

私服,就是公司內(nèi)部局域網(wǎng)的一臺(tái)服務(wù)器而已,你想一下,當(dāng)你的工程Project-A依賴別人的Project-B的接口,怎么做呢?沒有Maven的時(shí)候,當(dāng)然是copy Project-B jar到你的本地lib中引入,那么Maven的方式,很顯然需要其他人把Project-B deploy到私服倉(cāng)庫(kù)中供你使用。因此私服中存儲(chǔ)了本公司的內(nèi)部專用的jar!不僅如此,私服還充當(dāng)了中央倉(cāng)庫(kù)的鏡像,說白了就是一個(gè)代理!

中央倉(cāng)庫(kù):該倉(cāng)庫(kù)存儲(chǔ)了互聯(lián)網(wǎng)上的jar,由Maven團(tuán)隊(duì)來維護(hù),地址是:http://repo1.maven.org/maven2/。

2、關(guān)于使用

依賴管理Maven的插件以及生命周期的介紹

Maven的插件以及生命周期的介紹

其實(shí)這個(gè)標(biāo)簽揭示了jar的查找坐標(biāo):groupId、artifactId、version。

一般而言,我們可以到私服上輸入artifactId進(jìn)行搜索,或者到http://search.maven.org/、http://mvnrepository.com/上進(jìn)行查找確定坐標(biāo)。

version分為開發(fā)版本(Snapshot)和發(fā)布版本(Release),那么為什么要分呢?

在實(shí)際開發(fā)中,我們經(jīng)常遇到這樣的場(chǎng)景,比如A服務(wù)依賴于B服務(wù),A和B同時(shí)開發(fā),B在開發(fā)中發(fā)現(xiàn)了BUG,修改后,將版本由1.0升級(jí)為2.0,那么A必須也跟著在POM.XML中進(jìn)行版本升級(jí)。過了幾天后,B又發(fā)現(xiàn)了問題,進(jìn)行修改后升級(jí)版本發(fā)布,然后通知A進(jìn)行升級(jí)...可以說這是開發(fā)過程中的版本不穩(wěn)定導(dǎo)致了這樣的問題。

Maven,已經(jīng)替我們想好了解決方案,就是使用Snapshot版本,在開發(fā)過程中B發(fā)布的版本標(biāo)志為Snapshot版本,A進(jìn)行依賴的時(shí)候選擇Snapshot版本,那么每次B發(fā)布的話,會(huì)在私服倉(cāng)庫(kù)中,形成帶有時(shí)間戳的Snapshot版本,而A構(gòu)建的時(shí)候會(huì)自動(dòng)下載B最新時(shí)間戳的Snapshot版本!

3、既然Maven進(jìn)行了依賴管理,為什么還會(huì)出現(xiàn)依賴沖突?處理依賴沖突的手段是?

依賴的版本?

Maven的插件以及生命周期的介紹

首先來說,對(duì)于Maven而言,同一個(gè)groupId同一個(gè)artifactId下,只能使用一個(gè)version!

根據(jù)上圖的依賴順序,將使用1.2版本的jar。

現(xiàn)在,我們可以思考下了,比如工程中需要引入A、B,而A依賴1.0版本的C,B依賴2.0版本的C,那么問題來了,C使用的版本將由引入A、B的順序而定?這顯然不靠譜!如果A的依賴寫在B的依賴后面,將意味著最后引入的是1.0版本的C,很可能在運(yùn)行階段出現(xiàn)類(ClassNotFoundException)、方法(NoSuchMethodError)找不到的錯(cuò)誤(因?yàn)锽使用的是高版本的C)!

這里其實(shí)涉及到了2個(gè)概念:依賴傳遞(transitive)、Maven的最近依賴策略。

依賴傳遞:如果A依賴B,B依賴C,那么引入A,意味著B和C都會(huì)被引入。

Maven的最近依賴策略:如果一個(gè)項(xiàng)目依賴相同的groupId、artifactId的多個(gè)版本,那么在依賴樹(mvn dependency:tree)中離項(xiàng)目最近的那個(gè)版本將會(huì)被使用。(從這里可以看出Maven是不是有點(diǎn)小問題呢?能不能選擇高版本的進(jìn)行依賴么?據(jù)了解,Gradle就是version+策略)

現(xiàn)在,我們可以想想如何處理依賴沖突呢?

  • 想法1:要使用哪個(gè)版本,我們是清楚的,那么能不能不管如何依賴傳遞,都可以進(jìn)行版本鎖定呢?

  • 想法2:在依賴傳遞中,能不能去掉我們不想依賴的?

  • 想法3:既然是最近依賴策略,那么我們就直接使用顯式依賴指定版本,那不就是最靠近項(xiàng)目的么?

4、引入依賴的最佳實(shí)踐,提前發(fā)現(xiàn)問題!

在工程中,我們避免不了需要加一些依賴,也許加了依賴后運(yùn)行時(shí)才發(fā)現(xiàn)存在依賴沖突在去解決,似乎有點(diǎn)晚!那么能不能提前發(fā)現(xiàn)問題呢?

如果我們新加入一個(gè)依賴的話,那么先通過mvn dependency:tree命令形成依賴樹,看看我們新加入的依賴,是否存在傳遞依賴,傳遞依賴中是否和依賴樹中的版本存在沖突,如果存在多個(gè)版本沖突,利用上文的方式進(jìn)行解決!

5、Maven規(guī)范化目錄結(jié)構(gòu)

Maven的插件以及生命周期的介紹

src/main/java               –存放項(xiàng)目的.java文件  

src/main/resources      –存放項(xiàng)目資源文件。比方spring,hibernate配置文件

src/test/java                 –存放全部測(cè)試.java文件,比方JUnit測(cè)試類

src/test/resources        一測(cè)試資源文件

target                            一項(xiàng)目輸出位置,編譯完畢后的東西放到這里面

pom.xml                       一整個(gè)項(xiàng)目的構(gòu)建計(jì)劃書

這里需要注意2點(diǎn):

第一:src/main下內(nèi)容最終會(huì)打包到Jar/War中,而src/test下是測(cè)試內(nèi)容,并不會(huì)打包進(jìn)去。

第二:src/main/resources中的資源文件會(huì)COPY至目標(biāo)目錄,這是Maven的默認(rèn)生命周期中的一個(gè)規(guī)定動(dòng)作。(想一想,hibernate/mybatis的映射XML需要放入resources下,而不能在放在其他地方了)

6、Maven的生命周期

Maven生命周期:

Maven的插件以及生命周期的介紹

我們只需要注意一點(diǎn):執(zhí)行后面的命令時(shí),前面的命令自動(dòng)得到執(zhí)行。

實(shí)際上,我們最常用的就是這么幾個(gè):

clean:     有問題,多清理!
package:打成Jar or War包,會(huì)自動(dòng)進(jìn)行clean+compile
install:    將本地工程Jar上傳到本地倉(cāng)庫(kù)
deploy:  上傳到私服

7、關(guān)于scope依賴范圍

既然,Maven的生命周期存在編譯、測(cè)試、運(yùn)行這些過程,那么顯然有些依賴只用于測(cè)試,比如junit;有些依賴編譯用不到,只有運(yùn)行的時(shí)候才能用到,比如mysql的驅(qū)動(dòng)包在編譯期就用不到(編譯期用的是JDBC接口),而是在運(yùn)行時(shí)用到的;還有些依賴,編譯期要用到,而運(yùn)行期不需要提供,因?yàn)橛行┤萜饕呀?jīng)提供了,比如servlet-api在tomcat中已經(jīng)提供了,我們只需要的是編譯期提供而已。

總結(jié)來說:

compile:默認(rèn)的scope,運(yùn)行期有效,需要打入包中。
provided:編譯期有效,運(yùn)行期不需要提供,不會(huì)打入包中。servlet-api
runtime:編譯不需要,在運(yùn)行期有效,需要導(dǎo)入包中。(接口與實(shí)現(xiàn)分離)jdbc
test:測(cè)試需要,不會(huì)打入包中。junit
system:非本地倉(cāng)庫(kù)引入、存在系統(tǒng)的某個(gè)路徑下的jar。(一般不使用)

Nexus使用

Maven的插件以及生命周期的介紹

Maven的插件以及生命周期的介紹

到此,相信大家對(duì)“Maven的插件以及生命周期的介紹”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI