學(xué)習(xí)新技能
本篇文章主要是記錄學(xué)習(xí)過(guò)程中遇到的一些問(wèn)題,而不是教學(xué)
一、What
maven是一個(gè)項(xiàng)目管理工具,可以通過(guò)一小段描述信息來(lái)管理項(xiàng)目的構(gòu)建,報(bào)告和文檔的軟件項(xiàng)目。
Maven 是一個(gè)強(qiáng)大的項(xiàng)目管理和構(gòu)建自動(dòng)化工具,它通過(guò)抽象項(xiàng)目對(duì)象模型和構(gòu)建生命周期模型來(lái)對(duì)項(xiàng)目及其構(gòu)建過(guò)程進(jìn)行管理。Maven 最大化的消除了構(gòu)建的重復(fù),提升了構(gòu)建的效率與標(biāo)準(zhǔn)化。除此之外,Maven 還有依賴管理、自動(dòng)生成項(xiàng)目站點(diǎn)、代碼靜態(tài)檢查等特性。
什么是構(gòu)建工具?
構(gòu)建工具是將軟件項(xiàng)目構(gòu)建相關(guān)的過(guò)程自動(dòng)化的工具。構(gòu)建一個(gè)軟件項(xiàng)目通常包含以下一個(gè)或多個(gè)過(guò)程:
- 生成源碼(如果項(xiàng)目使用自動(dòng)生成源碼);
- 從源碼生成項(xiàng)目文檔;
- 編譯源碼;
- 將編譯后的代碼打包成JAR文件或者ZIP文件;
- 將打包好的代碼安裝到服務(wù)器、倉(cāng)庫(kù)或者其它的地方;
有些項(xiàng)目可能需要更多的過(guò)程才能完成構(gòu)建,這些過(guò)程一般也可以整合到構(gòu)建工具中,因此它們也可以實(shí)現(xiàn)自動(dòng)化。
自動(dòng)化構(gòu)建過(guò)程的好處是將手動(dòng)構(gòu)建過(guò)程中犯錯(cuò)的風(fēng)險(xiǎn)降到最低。而且,自動(dòng)構(gòu)建工具通常要比手動(dòng)執(zhí)行同樣的構(gòu)建過(guò)程要快。
目前個(gè)人對(duì)maven用途的理解主要有以下
- 消除構(gòu)建的重復(fù):
如果項(xiàng)目需要引入的多個(gè)A、B包,而他們的實(shí)現(xiàn)都需要C包。傳統(tǒng)模式下,A包和B包都會(huì)將C包放到自己的jar包中,這樣引入單獨(dú)的A包或者B包的時(shí)候就不需要再引入其他包。但是這就造成了如果同時(shí)需要A包和B包,就會(huì)在項(xiàng)目中出現(xiàn)兩個(gè)C包。而Maven的出現(xiàn)可以讓A包B包專心自己的代碼,將需要的C包通過(guò)Maven引入,同時(shí)在用Maven引入A包和B包的時(shí)候能夠識(shí)別只引入一個(gè)C包。 - 打包:
項(xiàng)目在開(kāi)發(fā)時(shí)為了啟動(dòng)速度使用Jetty作為web容器,希望在生產(chǎn)環(huán)境能夠使用Tomact。則可以使用Maven的依賴范圍scope中的provided
,來(lái)實(shí)現(xiàn)編譯時(shí)用Jetty包,運(yùn)行(打包后)時(shí)不引入Jetty包,從而可以直接放到Tomact容器中運(yùn)行而不會(huì)沖突。
<br />
二、Maven項(xiàng)目目錄結(jié)構(gòu)
maven目錄結(jié)構(gòu)、web項(xiàng)目目錄結(jié)構(gòu)
這是一個(gè)Maven項(xiàng)目的目錄結(jié)構(gòu)。正常情況下,用不同的框架或者方式建立的web項(xiàng)目,在開(kāi)發(fā)時(shí)為了滿足各自的自身需求會(huì)有不同的目錄結(jié)構(gòu),但在發(fā)布的時(shí)候就會(huì)發(fā)布一個(gè)統(tǒng)一的目錄結(jié)構(gòu),這一點(diǎn)需要注意。而在eclipse下,我們可以在
project
-properties
-Deployment Assembly
中設(shè)置發(fā)布時(shí)各個(gè)文件的輸出目錄。 以下為web項(xiàng)目目錄的標(biāo)準(zhǔn)結(jié)構(gòu)
上述文件和文件夾是一個(gè)web項(xiàng)目必備的。web容器初始化后會(huì)先根據(jù)WEB-INF
中的web.xml
解析客戶端請(qǐng)求,然后返回相應(yīng)的資源。
比如請(qǐng)求/admin/login
,服務(wù)器會(huì)先根據(jù)web.xml
查找并執(zhí)行class
中相應(yīng)的類文件。然后在通過(guò)各類文件中的路徑去尋找需要訪問(wèn)的資源(properties、css、jsp等等)。
<br />
三、倉(cāng)庫(kù)
maven的倉(cāng)庫(kù)有兩類:1.本地倉(cāng)庫(kù) 2.遠(yuǎn)程倉(cāng)庫(kù)。
其中遠(yuǎn)程倉(cāng)庫(kù)又有以下:2.1中央倉(cāng)庫(kù)、2.2私服、2.3其他倉(cāng)庫(kù)。
maven項(xiàng)目引用jar包是根據(jù)順序
- 當(dāng)依賴的范圍是system(默認(rèn))的時(shí)候先從本地查找jar包
- 如果本地沒(méi)有,則去中央倉(cāng)庫(kù)下載。
- 當(dāng)發(fā)現(xiàn)
setting.xml
中配置了中央倉(cāng)庫(kù)的鏡像后,去該鏡像地址下載。
ps:建立改變本地倉(cāng)庫(kù)位置,避免重裝以后要重新下載;同時(shí)配置倉(cāng)庫(kù)鏡像,這樣下載鏡像是能更。
<br />
四、Maven的依賴
1.依賴包的查詢是根據(jù)坐標(biāo)來(lái)進(jìn)行的,先查詢本地查詢?cè)偃ブ醒雮}(cāng)庫(kù)
2.依賴范圍scope
見(jiàn)下圖...................................
根據(jù)Java 面試題問(wèn)與答:編譯時(shí)與運(yùn)行時(shí)、Java泛型、依賴的官方文檔
這里的一些概念需要理解,比如編譯測(cè)試并不是指我們平時(shí)說(shuō)的編譯,而是一個(gè)具體的命令。如下圖的mvn compile
,實(shí)際上指編譯特定目錄下的文件。這里在看上面的test,意思是只有當(dāng)用測(cè)試命令的時(shí)候才會(huì)引入這個(gè)包。
重點(diǎn)理解provided,servlet經(jīng)常用。
3.依賴具有傳遞性。
對(duì)于依賴的傳遞而言,主要是針對(duì)compile作用域傳遞
當(dāng)傳遞沖突時(shí):
第一聲明者優(yōu)先原則:
【a-->b1.0】 【c-->b1.1】 【d-->a和c】,這個(gè)時(shí)候在d的pom中,哪一個(gè)依賴先寫(xiě)就使用先寫(xiě)依賴的版本,所以是b1.0路徑近者優(yōu)先原則:
【a-->b1.0】 【c-->b1.1】 【d-->a和c-->b1.0】 f-->d,c,如果路徑的長(zhǎng)短不一致就選擇最小路徑,所以是b1.1如果希望精確的控制依賴包,可以使用依賴的排除功能進(jìn)行控制
<exclusions>
<exclusion>
<groupId>lo4j</groupId>
<artiffactId>log4j</artiffactId>
</exclusion>
</exclussons>
4.依賴的聚合和繼承
maven聚合:聚合實(shí)際上是對(duì)多個(gè)項(xiàng)目同時(shí)進(jìn)行做處理,比如編譯、打包等。做法如下:創(chuàng)建一個(gè)新的maven項(xiàng)目,用于做其它項(xiàng)目的聚合,然后把pom.xml文件里的package標(biāo)簽里的jar改成pom,并去掉依賴,然后添加modules把其它項(xiàng)目引進(jìn)來(lái)。
maven繼承:繼承實(shí)際上是把相同的依賴提取出來(lái),放到一個(gè)父級(jí)項(xiàng)目的dependencyManagement標(biāo)簽里,然后子項(xiàng)目通過(guò)parent標(biāo)簽父級(jí)項(xiàng)目引進(jìn)來(lái)。
問(wèn)題2:有兩種打包war的方式
5.版本管理
總版本號(hào).分支版本號(hào).小版本號(hào)-里程碑版本
總版本號(hào)的變動(dòng)一般表示框架的變動(dòng)
分支版本號(hào):一般表示增加了一些功能
小版本號(hào):在分支版本上面進(jìn)行bug的修復(fù)
里程碑:SNAPSHOT快照-->alpha內(nèi)部測(cè)試-->beta公測(cè)-->release穩(wěn)定-->GA正式發(fā)布
<br />
四、生命周期
Maven的生命周期就是對(duì)所有的構(gòu)建過(guò)程進(jìn)行抽象和統(tǒng)一。包含了項(xiàng)目的清理、初始化、編譯、測(cè)試、打包、集成測(cè)試、驗(yàn)證、部署和站點(diǎn)生成等幾乎所有的構(gòu)建步驟。
Maven的生命周期是抽象的,即生命周期不做任何實(shí)際的工作,實(shí)際任務(wù)由插件完成,類似于設(shè)計(jì)模式中的模板方法。
三套獨(dú)立的生命周期
1、clean生命周期:清理項(xiàng)目,包含三個(gè)phase。
- pre-clean:執(zhí)行清理前需要完成的工作
- clean:清理上一次構(gòu)建生成的文件
- post-clean:執(zhí)行清理后需要完成的工作
2、default生命周期:構(gòu)建項(xiàng)目,重要的phase如下。
- validate:驗(yàn)證工程是否正確,所有需要的資源是否可用。
- compile:編譯項(xiàng)目的源代碼。
- test:使用合適的單元測(cè)試框架來(lái)測(cè)試已編譯的源代碼。這些測(cè)試不需要已打包和布署。
- Package:把已編譯的代碼打包成可發(fā)布的格式,比如jar。
- integration-test:如有需要,將包處理和發(fā)布到一個(gè)能夠進(jìn)行集成測(cè)試的環(huán)境。
- verify:運(yùn)行所有檢查,驗(yàn)證包是否有效且達(dá)到質(zhì)量標(biāo)準(zhǔn)。
- install:把包安裝到maven本地倉(cāng)庫(kù),可以被其他工程作為依賴來(lái)使用。
- Deploy:在集成或者發(fā)布環(huán)境下執(zhí)行,將最終版本的包拷貝到遠(yuǎn)程的repository,使得其他的開(kāi)發(fā)者或者工程可以共享。
3、site生命周期:建立和發(fā)布項(xiàng)目站點(diǎn),phase如下
- pre-site:生成項(xiàng)目站點(diǎn)之前需要完成的工作
- site:生成項(xiàng)目站點(diǎn)文檔
- post-site:生成項(xiàng)目站點(diǎn)之后需要完成的工作
- site-deploy:將項(xiàng)目站點(diǎn)發(fā)布到服務(wù)器
命令行和生命周期
各個(gè)生命周期相互獨(dú)立,一個(gè)生命周期的階段前后依賴。
舉例如下:
1、mvn clean
調(diào)用clean生命周期的clean階段,實(shí)際執(zhí)行pre-clean和clean階段
2、mvn test
調(diào)用default生命周期的test階段,實(shí)際執(zhí)行test以及之前所有階段
3、mvn clean install
調(diào)用clean生命周期的clean階段和default的install階段,實(shí)際執(zhí)行pre-clean和clean,install以及之前所有階段