一秃诵、Maven 是什么
Maven 是 Apache 軟件基金會(huì)維護(hù)的唯一一款自動(dòng)化構(gòu)建工具续搀,專注于服務(wù) Java 平臺(tái)的項(xiàng)目構(gòu)建和依賴管理。Maven 是采用純 Java 編寫的開源的基于項(xiàng)目對(duì)象模型 Project Object Model(POM)菠净,可以通過一小段描述信息來管理項(xiàng)目的構(gòu)建禁舷、報(bào)告和文檔的軟件項(xiàng)目管理工具歼冰,所有的項(xiàng)目配置信息都被定義在 pom.xml 的文件中震蒋。
POM 怎么理解?
Java 是面向?qū)ο缶幊烫呀穑瑢?duì)象就是類攀唯。而 Maven 是面向項(xiàng)目洁桌,把項(xiàng)目看做成是一個(gè)對(duì)象來進(jìn)行管理。是一個(gè)跨平臺(tái)的項(xiàng)目管理工具侯嘀,主要服務(wù)于 Java 平臺(tái)的項(xiàng)目構(gòu)建另凌、依賴管理和項(xiàng)目信息管理。
1??項(xiàng)目構(gòu)建:通過插件幫助完成項(xiàng)目的清理戒幔、編譯吠谢、測(cè)試、打包诗茎、部署工坊。比如之前除了編寫源代碼,每天有相當(dāng)一部分時(shí)間花在了編譯、運(yùn)行單元測(cè)試王污、生成文檔罢吃、打包和部署等繁瑣而又不得不做的工作上。
2??依賴管理:通過坐標(biāo)從 maven 倉(cāng)庫(kù)導(dǎo)入 Java 類庫(kù)(jar文件)昭齐。比如之前項(xiàng)目導(dǎo)入 jar 是通過 copy 方式導(dǎo)入項(xiàng)目中尿招,而且還會(huì)存在 jar 之間的依賴和沖突。而 maven 解決了這些問題阱驾,幫助下載 Jar 包泊业。
3??倉(cāng)庫(kù)管理:提供統(tǒng)一管理所有 Jar 包的工具。
4??項(xiàng)目信息管理:項(xiàng)目描述啊易、開發(fā)者列表、版本控制系統(tǒng)地址等饮睬。比如發(fā)布版本之后可能還要對(duì)版本進(jìn)行升級(jí)租谈。
二、Maven 可以做什么
①添加第三方 jar 包捆愁。
②jar 包之間的依賴關(guān)系:Maven 可以自動(dòng)的將當(dāng)前 jar 包所依賴的其他所有 jar 包全部導(dǎo)入進(jìn)來割去。
③獲取第三方 jar 包:Maven 提供了一個(gè)完全統(tǒng)一規(guī)范的 jar 包管理體系,只需要在項(xiàng)目中以坐標(biāo)的方式依賴一個(gè) jar 包昼丑,Maven 就會(huì)自動(dòng)從中央倉(cāng)庫(kù)下載到本地倉(cāng)庫(kù)呻逆。
④將項(xiàng)目拆分成多個(gè)工程模塊。
⑤構(gòu)建項(xiàng)目(打包菩帝,編譯等)咖城。
三、構(gòu)建項(xiàng)目的幾個(gè)主要環(huán)節(jié)
①清理(clean):刪除以前的編譯結(jié)果呼奢,為重新編譯做好準(zhǔn)備宜雀。
②編譯(compile):將 Java 源程序編譯為字節(jié)碼文件。
③測(cè)試(test):針對(duì)項(xiàng)目中的關(guān)鍵點(diǎn)進(jìn)行測(cè)試握础,確保項(xiàng)目在迭代開發(fā)過程中關(guān)鍵點(diǎn)的正確性辐董。
④報(bào)告:在每一次測(cè)試后以標(biāo)準(zhǔn)的格式記錄和展示測(cè)試結(jié)果。
⑤打包(package):將一個(gè)包含諸多文件的工程封裝為一個(gè)壓縮文件用于安裝或部署禀综。Java 工程對(duì)應(yīng) jar 包简烘,Web 工程對(duì)應(yīng) war 包。
⑥安裝(install):在 Maven 環(huán)境下特指將打包的結(jié)果——jar 包或 war 包安裝到本地倉(cāng)庫(kù)中定枷。
⑦部署(deploy):將打包的結(jié)果部署到遠(yuǎn)程倉(cāng)庫(kù)或?qū)?war 包部署到服務(wù)器上運(yùn)行孤澎。
四、Maven常用命令
①mvn -version/-v —— 顯示版本信息
②mvn clean —— 清空生成的文件
③mvn compile —— 編譯
④mvn test —— 編譯并測(cè)試
⑤mvn package —— 生成target目錄依鸥,編譯亥至、測(cè)試代碼,生成測(cè)試報(bào)告,生成 jar/war 文件
⑥mvn site —— 生成項(xiàng)目相關(guān)信息的網(wǎng)站
⑦mvn clean compile —— 表示先運(yùn)行清理之后運(yùn)行編譯姐扮,會(huì)將代碼編譯到 target 文件夾中
⑧mvn clean package —— 運(yùn)行清理和打包
⑨mvn clean install —— 運(yùn)行清理和安裝絮供,會(huì)將打好的包安裝到本地倉(cāng)庫(kù)中,以便其他的項(xiàng)目可以調(diào)用
⑩mvn clean deploy —— 運(yùn)行清理和發(fā)布
五茶敏、Maven核心概念
Maven 能夠?qū)崿F(xiàn)自動(dòng)化構(gòu)建是和它的內(nèi)部原理分不開的壤靶,這里從 Maven 的九個(gè)核心概念入手,看看 Maven 是如何實(shí)現(xiàn)自動(dòng)化構(gòu)建的惊搏。
①POM
②約定的目錄結(jié)構(gòu)
③坐標(biāo)
④依賴管理
⑤倉(cāng)庫(kù)管理
⑥生命周期
⑦插件和目標(biāo)
⑧繼承
⑨聚合
Maven 的核心程序中僅僅定義了抽象的生命周期贮乳,而具體的操作則是由 Maven 的插件來完成的√窆撸可是 Maven 的插件并不包含在 Maven 的核心程序中向拆,在首次使用時(shí)需要聯(lián)網(wǎng)下載。下載得到的插件會(huì)被保存到本地倉(cāng)庫(kù)中酪耳。本地倉(cāng)庫(kù)默認(rèn)的位置是:~.m2\repository浓恳。
1??Maven 約定的工程目錄Java 開發(fā)領(lǐng)域普遍認(rèn)同的一個(gè)觀點(diǎn):約定>配置>編碼(能用配置解決的問題就不編碼,能基于約定的就不配置)
2??pom:Project Object Model 項(xiàng)目對(duì)象模型
將 Java 工程的相關(guān)信息封裝為對(duì)象作為便于操作和管理的模型碗暗。Maven 工程的核心配置颈将。
3??Maven 的坐標(biāo)
使用如下三個(gè)向量在 Maven 的倉(cāng)庫(kù)中唯一的確定一個(gè) Maven 工程:
①groupid:公司或組織的域名倒序+當(dāng)前項(xiàng)目名稱
②artifactId:當(dāng)前項(xiàng)目的模塊名稱
③version:當(dāng)前模塊的版本
<groupId>com.xxp</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
如何通過坐標(biāo)到倉(cāng)庫(kù)中查找 jar 包?將 gav 三個(gè)向量連起來com.xxp+demo+0.0.1-SNAPSHOT
復(fù)制代碼以連起來的字符串作為目錄結(jié)構(gòu)到倉(cāng)庫(kù)中查找com/xxp/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.jar
※ 注意:自己的 Maven 工程必須執(zhí)行安裝操作才會(huì)進(jìn)入倉(cāng)庫(kù)言疗。安裝的命令是:mvn install
4??Maven 中最關(guān)鍵的部分:依賴
使用 Maven 最主要的就是使用它的依賴管理功能晴圾。要理解和掌握 Maven 的依賴管理,需要解決以下幾個(gè)問題:
①依賴的目的是什么
當(dāng) A jar 包用到了 B jar 包中的某些類時(shí)噪奄,A 就對(duì) B 產(chǎn)生了依賴死姚,這是概念上的描述。那么如何在項(xiàng)目中以依賴的方式引入一個(gè)需要的 jar 包呢梗醇? 就是使用 dependency 標(biāo)簽指定被依賴 jar 包的坐標(biāo)就可以了知允。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
②依賴的范圍
有時(shí)依賴信息中除了目標(biāo) jar 包的坐標(biāo)還有一個(gè) scope 設(shè)置,這就是依賴的范圍叙谨。依賴的范圍有幾個(gè)可選值温鸽,常用的有:compile、test手负、provided 三個(gè)涤垫,當(dāng)然還有不常用的 runtime、system..
- compile:默認(rèn)范圍竟终,編譯測(cè)試運(yùn)行都有效
- provided:在編譯和測(cè)試時(shí)有效
- runtime:在測(cè)試和運(yùn)行時(shí)有效
- test:只在測(cè)試時(shí)有效
- system:在編譯和測(cè)試時(shí)有效,與本機(jī)系統(tǒng)關(guān)聯(lián)统捶,可移植性差
③依賴的傳遞性
A 依賴 B榆芦,B 依賴 C堪夭,A 能否使用 C 呢爬迟?那要看 B 依賴 C 的范圍是不是 compile雕旨,如果是則可用闺鲸,否則不可用。
④依賴的排除
如果在當(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 排除乃坤。
<dependency>
<groupId>com.xxp</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
⑤統(tǒng)一管理所依賴 jar 包的版本苛让,對(duì)同一個(gè)框架的一組 jar 包最好使用相同的版本沟蔑。為了方便升級(jí)框架,可以將 jar 包的版本信息統(tǒng)一提取出來狱杰,統(tǒng)一聲明版本號(hào):
<properties>
<starfish.spring.version>4.1.1.RELEASE</starfish.spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
引用前面聲明的版本號(hào):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${starfish.spring.version}</version>
<scope>compile</scope>
</dependency>
⑥依賴的原則:解決 jar 包沖突
- 路徑最短者優(yōu)先
- 路徑相同時(shí)先聲明者優(yōu)先
5??倉(cāng)庫(kù)
①本地倉(cāng)庫(kù):為當(dāng)前本機(jī)電腦上的所有 Maven 工程服務(wù)。
②遠(yuǎn)程倉(cāng)庫(kù)私服:架設(shè)在當(dāng)前局域網(wǎng)環(huán)境下错沽,為當(dāng)前局域網(wǎng)范圍內(nèi)的所有 Maven 工程服務(wù)
③中央倉(cāng)庫(kù):架設(shè)在 Internet 上簿晓,為全世界所有 Maven 工程服務(wù)
④中央倉(cāng)庫(kù)的鏡像:架設(shè)在各個(gè)大洲,為中央倉(cāng)庫(kù)分擔(dān)流量千埃。減輕中央倉(cāng)庫(kù)的壓力憔儿,同時(shí)更快的響應(yīng)用戶請(qǐng)求,比如阿里的鏡像放可。
⑤不管是什么樣的 jar 包谒臼,在倉(cāng)庫(kù)中都是按照坐標(biāo)生成目錄結(jié)構(gòu),所以可以通過統(tǒng)一的方式查詢或依賴耀里,查詢地址:mvnrepository.com
6??生命周期
①什么是 Maven 的生命周期蜈缤?
Maven 生命周期定義了各個(gè)構(gòu)建環(huán)節(jié)的執(zhí)行順序,有了這個(gè)清單冯挎,Maven 就可以自動(dòng)化的執(zhí)行構(gòu)建命令了劫樟。Maven 有三套相互獨(dú)立的生命周期,分別是:
- Clean Lifecycle 在進(jìn)行真正的構(gòu)建之前進(jìn)行一些清理工作
- Default Lifecycle 構(gòu)建的核心部分织堂,編譯,測(cè)試奶陈,打包易阳,安裝,部署等等
- Site Lifecycle 生成項(xiàng)目報(bào)告吃粒,站點(diǎn)潦俺,發(fā)布站點(diǎn)
它們是相互獨(dú)立的,可以僅僅調(diào)用 clean 來清理工作目錄徐勃,僅僅調(diào)用 site 來生成站點(diǎn)事示。當(dāng)然也可以直接執(zhí)行mvn clean install site
運(yùn)行所有這三套生命周期。 每套生命周期都由一組階段(Phase)組成僻肖,平時(shí)在命令行輸入的命令總會(huì)對(duì)應(yīng)于一個(gè)特定的階段肖爵。比如,運(yùn)行 mvn clean臀脏,這個(gè) clean 是 Clean 生命周期的一個(gè)階段劝堪。有 Clean 生命周期冀自,也有 clean 階段。
②Clean 生命周期
- pre-clean 執(zhí)行一些需要在 clean 之前完成的工作
- clean 移除所有上一次構(gòu)建生成的文件
- post-clean 執(zhí)行一些需要在 clean 之后立刻完成的工作
③Site 生命周期
- 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 相當(dāng)強(qiáng)大 的功能余境,Manager 比較喜歡驻呐,文檔及統(tǒng)計(jì)數(shù)據(jù)自動(dòng)生成,很好看芳来。
④Default 生命周期
Default 生命周期是 Maven 生命周期中最重要的一個(gè)含末,絕大部分工作都發(fā)生在這個(gè)生命周期中(列出一些重要階段)
- validate:驗(yàn)證工程是否正確,所有需要的資源是否可用绣张。
- compile:編譯項(xiàng)目的源代碼答渔。
- test:使用合適的單元測(cè)試框架來測(cè)試已編譯的源代碼。這些測(cè)試不需要已打包和布署侥涵。
- package:把已編譯的代碼打包成可發(fā)布的格式沼撕,比如 jar、war 等芜飘。
- 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ù),可以被其他工程作為依賴來使用娶牌。
- deploy:在集成或者發(fā)布環(huán)境下執(zhí)行奔浅,將最終版本的包拷貝到遠(yuǎn)程的repository,使得其他的開發(fā)者或者工程可以共享
⑤生命周期與自動(dòng)化構(gòu)建
運(yùn)行任何一個(gè)階段的時(shí)候诗良,它前面的所有階段都會(huì)被運(yùn)行汹桦,例如我們運(yùn)行 mvn install 的時(shí)候,代碼會(huì)被編譯鉴裹,測(cè)試舞骆,打包。這就是 Maven 為什么能夠自動(dòng)執(zhí)行構(gòu)建過程的各個(gè)環(huán)節(jié)的原因径荔。此外督禽,Maven 的插件機(jī)制是完全依賴 Maven 的生命周期的,因此理解生命周期至關(guān)重要总处。
7??插件和目標(biāo)
- Maven 的核心僅僅定義了抽象的生命周期狈惫,具體的任務(wù)都是交由插件完成的
- 每個(gè)插件都能實(shí)現(xiàn)多個(gè)功能,每個(gè)功能就是一個(gè)插件目標(biāo)
- Maven 的生命周期與插件目標(biāo)相互綁定鹦马,以完成某個(gè)具體的構(gòu)建任務(wù) 例如:compile 就是插件 maven-compiler-plugin 的一個(gè)目標(biāo)虱岂;pre-clean 是插件 maven-clean-plugin 的一個(gè)目標(biāo)
8??繼承
為什么需要繼承機(jī)制玖院? 由于非 compile 范圍的依賴信息是不能在“依賴鏈”中傳遞的,所以有需要的工程只能單獨(dú)配置第岖。創(chuàng)建父工程和創(chuàng)建一般的 Java 工程操作一致难菌,唯一需要注意的是:打包方式處要設(shè)置為 pom。在子工程中引用父工程 蔑滓,從當(dāng)前目錄到父項(xiàng)目的 pom.xml 文件的相對(duì)路徑郊酒。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<!-- 以當(dāng)前文件為基準(zhǔn)的父工程pom.xml文件的相對(duì)路徑 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
此時(shí)如果子工程的 groupId 和 version 如果和父工程重復(fù)則可以刪除。在父工程中管理依賴 將 Parent 項(xiàng)目中的 dependencies 標(biāo)簽键袱,用 dependencyManagement 標(biāo)簽括起來:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子項(xiàng)目中重新指定需要的依賴燎窘,刪除范圍和版本號(hào):
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
9??聚合
為什么要使用聚合?將多個(gè)工程拆分為模塊后蹄咖,需要手動(dòng)逐個(gè)安裝到倉(cāng)庫(kù)后依賴才能夠生效褐健。修改源碼后也需要逐個(gè)手動(dòng)進(jìn) 行 clean 操作。而使用了聚合之后就可以批量進(jìn)行 Maven 工程的安裝澜汤、清理工作蚜迅。如何配置聚合? 在總的聚合工程中使用 modules/module 標(biāo)簽組合俊抵,指定模塊工程的相對(duì)路徑即可:
<!-- 配置聚合 -->
<modules>
<!-- 指定各個(gè)子工程的相對(duì)路徑 -->
<module>starfish-learn-grpc</module>
<module>starfish-learn-kafka</module>
<module>starfish-web-demo</module>
</modules>
六谁不、package install deploy 區(qū)別
1??打包區(qū)別
①mvn package
:打包到本項(xiàng)目,一般在項(xiàng)目target
目錄下徽诲。
②mvn install
:打包到本地倉(cāng)庫(kù)刹帕,如果沒設(shè)置Maven
本地倉(cāng)庫(kù),一般在用戶/.m2
目錄下谎替。
③mvn deploy
:打包上傳到遠(yuǎn)程倉(cāng)庫(kù)偷溺,如:私服nexus
等,需要配置pom
文件钱贯。
2??打包過程
① mvn clean package
依次執(zhí)行:clean
挫掏、resources
、compile
喷舀、testResources
、testCompile
淋肾、test
硫麻、jar
(打包)。
②mvn clean install
依次執(zhí)行:clean
樊卓、resources
拿愧、compile
、testResources
碌尔、testCompile
浇辜、test
券敌、jar
(打包)、install
柳洋。
③mvn clean deploy
依次執(zhí)行:clean
待诅、resources
、compile
熊镣、testResources
卑雁、testCompile
、test
绪囱、jar
(打包)测蹲、install
、deploy
鬼吵。
由上面分析主要區(qū)別如下:
①package
命令:完成項(xiàng)目編譯扣甲、單元測(cè)試、打包功能齿椅,但打包文件未部署到本地Maven
倉(cāng)庫(kù)和遠(yuǎn)程Maven
倉(cāng)庫(kù)琉挖。
②install
命令:完成項(xiàng)目編譯、單元測(cè)試媒咳、打包功能粹排,同時(shí)把打包文件部署到本地Maven
倉(cāng)庫(kù),但未部署到遠(yuǎn)程Maven
倉(cāng)庫(kù)涩澡。
③deploy
命令:完成項(xiàng)目編譯顽耳、單元測(cè)試、打包功能妙同,同時(shí)把打包文件部署到本地Maven
倉(cāng)庫(kù)和遠(yuǎn)程Maven
倉(cāng)庫(kù)射富。
七、理解 Maven 中的 SNAPSHOT 版本和正式版本
Maven 中建立的依賴管理方式基本已成為 Java 語言依賴管理的事實(shí)標(biāo)準(zhǔn)粥帚,Maven 的替代者 Gradle 也基本沿用了 Maven 的依賴管理機(jī)制胰耗。在 Maven 依賴管理中,唯一標(biāo)識(shí)一個(gè)依賴項(xiàng)是由該依賴項(xiàng)的三個(gè)屬性構(gòu)成的芒涡,分別是 groupId柴灯、artifactId 以及 version。這三個(gè)屬性可以唯一確定一個(gè)組件(Jar包或者War包)费尽。
其實(shí)在 Nexus 倉(cāng)庫(kù)中赠群,一個(gè)倉(cāng)庫(kù)一般分為 public(Release) 倉(cāng)和 SNAPSHOT 倉(cāng),前者存放正式版本旱幼,后者存放快照版本查描。如果在項(xiàng)目配置文件中(無論是 build.gradle 還是 pom.xml)指定的版本號(hào)帶有“-SNAPSHOT”后綴,比如版本號(hào)為“Junit-1.0-SNAPSHOT”,那么打出的包就是一個(gè)快照版本冬三。
兩個(gè)版本的主要區(qū)別在于匀油,本地獲取這些依賴的機(jī)制有所不同。假設(shè)依賴一個(gè)庫(kù)的正式版本勾笆,構(gòu)建的時(shí)候構(gòu)建工具會(huì)先在本次倉(cāng)庫(kù)中查找是否已經(jīng)有了這個(gè)依賴庫(kù)敌蚜,如果沒有的話才會(huì)去遠(yuǎn)程倉(cāng)庫(kù)中去拉取。所以假設(shè)發(fā)布了 Junit-1.0.jar 到了遠(yuǎn)程倉(cāng)庫(kù)匠襟,有一個(gè)項(xiàng)目依賴了這個(gè)庫(kù)钝侠,它第一次構(gòu)建的時(shí)候會(huì)把該庫(kù)從遠(yuǎn)程倉(cāng)庫(kù)中下載到本地倉(cāng)庫(kù)緩存,以后再次構(gòu)建都不會(huì)去訪問遠(yuǎn)程倉(cāng)庫(kù)了酸舍。所以如果修改了代碼帅韧,向遠(yuǎn)程倉(cāng)庫(kù)中發(fā)布了新的軟件包,但仍然叫 Junit-1.0.jar啃勉,那么依賴這個(gè)庫(kù)的項(xiàng)目就無法得到最新更新忽舟。只有在重新發(fā)布的時(shí)候升級(jí)版本,比如叫做 Junit-1.1.jar淮阐,然后通知依賴該庫(kù)的項(xiàng)目組也修改依賴版本為 Junit-1.1叮阅,這樣才能使用到最新添加的功能。
在團(tuán)隊(duì)內(nèi)部泣特,如此開發(fā)特別繁瑣浩姥。假設(shè)有兩個(gè)小組負(fù)責(zé)維護(hù)兩個(gè)組件,pay-service 和 pay-ui状您,其中 pay-ui 項(xiàng)目依賴于 pay-service勒叠。而這兩個(gè)項(xiàng)目每天都會(huì)構(gòu)建多次,如果每次構(gòu)建都要升級(jí) pay-service 的版本膏孟,想想都頭疼眯分。SNAPSHOT 版本就是解決這個(gè)問題的。日常構(gòu)建時(shí)可以構(gòu)建 pay-service 的快照版本柒桑,比如 pay-service-1.0-SNAPSHOT.jar弊决,而 pay-ui 依賴該快照版本。每次 pay-ui 構(gòu)建時(shí)魁淳,會(huì)優(yōu)先去遠(yuǎn)程倉(cāng)庫(kù)中查看是否有最新的 pay-service-1.0-SNAPSHOT.jar飘诗,如果有則下載下來使用。即使本地倉(cāng)庫(kù)中已經(jīng)有了 pay-service-1.0-SNAPSHOT.jar界逛,它也會(huì)嘗試去遠(yuǎn)程倉(cāng)庫(kù)中查看同名的 jar 是否是最新的昆稿。然而,這樣不就不能充分利用本地倉(cāng)庫(kù)的緩存機(jī)制了嗎仇奶?其實(shí)在配置 Maven 的 Repository 的時(shí)候中有個(gè)配置項(xiàng)貌嫡,可以配置對(duì)于 SNAPSHOT 版本向遠(yuǎn)程倉(cāng)庫(kù)中查找的頻率。頻率共有四種该溯,分別是 always岛抄、daily、interval狈茉、never夫椭。當(dāng)本地倉(cāng)庫(kù)中存在需要的依賴項(xiàng)目時(shí),always 是每次都去遠(yuǎn)程倉(cāng)庫(kù)查看是否有更新氯庆,daily 是只在第一次的時(shí)候查看是否有更新蹭秋,當(dāng)天的其它時(shí)候則不會(huì)查看;interval 允許設(shè)置一個(gè)分鐘為單位的間隔時(shí)間堤撵,在這個(gè)間隔時(shí)間內(nèi)只會(huì)去遠(yuǎn)程倉(cāng)庫(kù)中查找一次仁讨,never 是不會(huì)去遠(yuǎn)程倉(cāng)庫(kù)中查找(這種就和正式版本的行為一樣了)。
Maven版本的配置方式為:
<repository>
<id>myRepository</id>
<url>...</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>XXX</updatePolicy>
</snapshots>
</repository>
其中 updatePolicy 就是那 4 種類型之一实昨。如果配置間隔時(shí)間更新洞豁,可以寫作 interval:XX (XX是間隔分鐘數(shù))。daily 配置是默認(rèn)值荒给。而在 Gradle丈挟,可以設(shè)置本地緩存的更新策略:
configurations.all {
// check for updates every build
resolutionStrategy.cacheChangingModulesFor 0,'seconds'
}
當(dāng)然也可以按照分鐘或者小時(shí)來設(shè)置:
configurations.all {
resolutionStrategy.cacheChangingModulesFor 10, ‘minutes'
}
configurations.all {
resolutionStrategy.cacheChangingModulesFor 4, ‘hours'
}
日常開發(fā),可以頻繁發(fā)布 SNAPSHOT 版本志电,以便讓其它項(xiàng)目能實(shí)時(shí)的使用到最新的功能做聯(lián)調(diào)曙咽;當(dāng)版本趨于穩(wěn)定時(shí),再發(fā)布一個(gè)正式版本挑辆,供正式使用例朱。當(dāng)然在做正式發(fā)布時(shí),也要確保當(dāng)前項(xiàng)目的依賴項(xiàng)中不包含對(duì)任何 SNAPSHOT 版本的依賴之拨,保證正式版本的穩(wěn)定性茉继。
八、其它流行的構(gòu)建工具(了解)
Java 世界蚀乔,目前在被使用的常用構(gòu)建工具有三個(gè):Ant烁竭、Maven、Gradle吉挣。
1??Ant 的核心是由 Java 編寫派撕,采用 XML 作為構(gòu)建腳本,這樣就允許在任何環(huán)境下睬魂,運(yùn)行構(gòu)建终吼。Ant 基于任務(wù)鏈思想,任務(wù)之間定義依賴氯哮,形成先后順序际跪。缺點(diǎn)是使用 XML 定義構(gòu)建腳本,導(dǎo)致腳本臃腫。Ant 自身沒有為項(xiàng)目構(gòu)建提供指導(dǎo)姆打,導(dǎo)致每個(gè) build 腳本都不一樣良姆,開發(fā)人員對(duì)于每個(gè)項(xiàng)目都需要去熟悉腳本內(nèi)容,沒有提供在 Ant 生態(tài)環(huán)境內(nèi)的依賴管理工具幔戏。
2??Maven 團(tuán)隊(duì)意識(shí)到 Ant 的缺陷玛追,采用標(biāo)準(zhǔn)的項(xiàng)目布局,和統(tǒng)一的生命周期闲延,采用約定由于配置的思想痊剖,減少構(gòu)建腳本需要的編寫內(nèi)容,活躍的社區(qū)垒玲,可以方便找到合適的插件陆馁,強(qiáng)大的依賴管理工具。缺點(diǎn)是采用默認(rèn)的結(jié)構(gòu)和生命周期合愈,太過限制氮惯,編寫插件擴(kuò)展麻煩,XML 作為構(gòu)建腳本想暗。
3??Gradle 同時(shí)擁有 Ant 和 Maven 的優(yōu)點(diǎn)妇汗,它是基于 Groovy 的 DSL,提供聲明式的構(gòu)建語言说莫,采用標(biāo)準(zhǔn)的項(xiàng)目布局杨箭,但擁有完全的可配置性,就是可以改储狭,通過插件互婿,提供默認(rèn)的構(gòu)建生命周期,也可以自己定義任務(wù)辽狈,單獨(dú)運(yùn)行任務(wù)慈参,定義任務(wù)間的依賴,強(qiáng)大的依賴管理工具刮萌,與 Maven 和 Ivy 倉(cāng)庫(kù)結(jié)合驮配,與 Ant 天生兼容,有效的重用 Ant 的任務(wù)着茸,多種實(shí)現(xiàn)插件的方式壮锻,強(qiáng)大的官方插件庫(kù),從構(gòu)建級(jí)別涮阔,支持從 Ant 或者 Maven 的逐步遷移猜绣,通過包裝器,無縫的在各個(gè)平臺(tái)運(yùn)行敬特。
4??如何識(shí)別項(xiàng)目構(gòu)建工具掰邢,一般來說牺陶,一個(gè)項(xiàng)目的根目錄中就會(huì)包含構(gòu)建工具的配置文件信息,也表明了該項(xiàng)目使用的構(gòu)建工具辣之,通常有如下的對(duì)應(yīng)關(guān)系:
①build.xml - 該項(xiàng)目使用 Ant 構(gòu)建
②pom.xml - 該項(xiàng)目使用 Maven 構(gòu)建
③build.gradle - 該項(xiàng)目使用 Gradle 構(gòu)建