国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~

這篇具有很好參考價(jià)值的文章主要介紹了【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享


上文詳細(xì)介紹了Maven 坐標(biāo)和依賴,坐標(biāo)和依賴是任何一個(gè)構(gòu)件在Maven 世界中的邏輯表示方式;而構(gòu)件的物理表示方式是文件, Maven 通過倉(cāng)庫(kù)來(lái)統(tǒng)一管理這些文件。本文將詳細(xì)介紹 Maven 倉(cāng)庫(kù),在了解了Maven 如何使用倉(cāng)庫(kù)之后,將能夠更高效地使用 Maven。

1?? 什么是Maven倉(cāng)庫(kù)

在Maven 世界中,任何一個(gè)依賴、插件或者項(xiàng)目構(gòu)建的輸出,都可以稱為構(gòu)件。例如, 依賴 log4j-1.2.15.jar是一個(gè)構(gòu)件,插件 maven-compiler-plugin-2.0.2.jar 是一個(gè)構(gòu)件,account-email 項(xiàng)目構(gòu)建完成后的輸出 account-email-1.0.0-SNAPSHOT.jar 也是一個(gè)構(gòu)件。 任何一個(gè)構(gòu)件都有一組坐標(biāo)唯一標(biāo)識(shí)。

在一臺(tái)工作站上,可能會(huì)有幾十個(gè) Maven 項(xiàng)目,所有項(xiàng)目都使用 maven-compiler-plugin, 這些項(xiàng)目中的大部分都用到了 log4j, 有一小部分用到了Spring Framework, 還有另外一小部分用到了Struts2。 在每個(gè)有需要的項(xiàng)目中都放置一份重復(fù)的 log4j 或者 struts2 顯然不是最好的解決方案,這樣做不僅造成了磁盤空間的浪費(fèi),而且也難于統(tǒng)一管理,文件的復(fù)制等操作也會(huì)降低構(gòu)建的速度。而實(shí)際情況是,在不使用Maven 的那些項(xiàng)目中,我們往往就能發(fā)現(xiàn)命名為lib/的目錄,各個(gè)項(xiàng)目 lib/目錄下的內(nèi)容存在大量的重復(fù)。

得益于坐標(biāo)機(jī)制,任何Maven 項(xiàng)目使用任何一個(gè)構(gòu)件的方式都是完全相同的。在此基礎(chǔ)上, Maven 可以在某個(gè)位置統(tǒng)一存儲(chǔ)所有 Maven 項(xiàng)目共享的構(gòu)件,這個(gè)統(tǒng)一的位置就是 倉(cāng)庫(kù)。實(shí)際的Maven 項(xiàng)目將不再各自存儲(chǔ)其依賴文件,它們只需要聲明這些依賴的坐標(biāo), 在需要的時(shí)候 (例如,編譯項(xiàng)目的時(shí)候需要將依賴加入到 classpath 中 ) , Maven 會(huì)自動(dòng)根據(jù)坐標(biāo)找到倉(cāng)庫(kù)中的構(gòu)件,并使用它們。

為了實(shí)現(xiàn)重用,項(xiàng)目構(gòu)建完畢后生成的構(gòu)件也可以安裝或者部署到倉(cāng)庫(kù)中,供其他項(xiàng)目使用。

2?? 倉(cāng)庫(kù)的布局

任何一個(gè)構(gòu)件都有其唯一的坐標(biāo),根據(jù)這個(gè)坐標(biāo)可以定義其在倉(cāng)庫(kù)中的唯一存儲(chǔ)路徑, 這便是Maven 的倉(cāng)庫(kù)布局方式。例如,log4j:log4j:1.2.15 這一依賴,其對(duì)應(yīng)的倉(cāng)庫(kù)路徑為 log4j/log4j/1.2.15/log4j-1.2.15.jar, 細(xì)心的朋友可以觀察到,該路徑與坐標(biāo)的大致對(duì)應(yīng)關(guān)系為 groupId/artifactId/version/artifactId-version.packaging。 下面看一段 Maven 的源碼,并結(jié)合具體的實(shí)例來(lái)理解 Maven 倉(cāng)庫(kù)的布局方式,見如下代碼:

private static final char PATH_SEPARATOR='/';
private static final char GROUP_SEPARATOR='.';
private static final char ARTIFACT_SEPARATOR='-';

public String pathOf(Artifact artifact){
	ArtifactHandler artifactHandler = artifact.getArtifactHandler();
	StringBuilder path = new StringBuilder(128);
	path.append(formatAsDirectory(artifact.getGroupId())).append(                     PATH_SEPARATOR );
	path,append(artifact.getArtifactId()).append(PATH_SEPARATOR); 
	path.append(artifact.getBaseVersion()).append(PATH_SEPARATOR);
	path.append(artifact.getArtifactId()).append(ARTIFACT_SEPARATOR)
		.append(artifact.getVersion());
	
	if(artifact.hasClassifier()){
		path.append(ARTIFACT_SEPARATOR).append(artifact.getClassifier());
	}
	if(artifactHandler.getExtension() != null && artifactHandler.getExtension().length() >0)
	{
		path.append(GROUP_SEPARATOR).append(artifactHandler.getExtension());
	}
	return path.toString();
}

private String formatAsDirectory(String directory){
	return directory.replace(GROUP_SEPARATOR,PATH_SEPARATOR);
}

pathOf() 方法的目的是根據(jù)構(gòu)件信息生成其在倉(cāng)庫(kù)中的路徑。在閱讀本段代碼之前, 可以先回顧一下上文的相關(guān)內(nèi)容。這里根據(jù)一個(gè)實(shí)際的例子來(lái)分析路徑的生成,考慮這樣一 個(gè)構(gòu)件:groupId =org.testng、artifactId =testng、version =5.8、clasifier =jdk15、packaging =jar, 其對(duì)應(yīng)的路徑按如下步驟生成:
(1)基于構(gòu)件的 groupId 準(zhǔn)備路徑,formatAsDirectory()groupId 中的句點(diǎn)分隔符轉(zhuǎn)換成 路徑分隔符。該例中, groupld org.testng 就會(huì)被轉(zhuǎn)換成 org/testng, 之后再加一個(gè)路徑分隔符斜杠,那么, org.testng 就成了 org/testng/。
(2)基于構(gòu)件的 artifactId 準(zhǔn)備路徑,也就是在前面的基礎(chǔ)上加上 artifactId 以及一個(gè)路徑分隔符。該例中的 artifactIdtestng, 那么,在這一步過后,路徑就成為了org/testng/testng/
(3)使用版本信息。在前面的基礎(chǔ)上加上 version 和路徑分隔符。該例中版本是5.8, 那么路徑就成為了 org/testng/tesgng/5.8/。
(4)依次加上 artifactId, 構(gòu)件分隔符連字號(hào),以及 version, 于是構(gòu)建的路徑就變成了 org/testng/testng/5.8/testng-5.8。大家可能注意到了,這里使用了 arifactId.gelVersion(), 而上一 步用的是 artifactId. getBaseVersion(), baseVersion 主要是為SNAPSHOT 版本服務(wù)的,
例如 version為1.0-SNAPSHOT 的構(gòu)件,其 baseVersion 就是1.0。
(5)如果構(gòu)件有 classifier, 就加上構(gòu)件分隔符和 classifier。 該例中構(gòu)件的 classifier 是 jdk15, 那么路徑就變成 org/testng/testng/5.8/testng-5.8-jdk5。
(6)檢查構(gòu)件的 extension, 若 estension 存在,則加上句點(diǎn)分隔符和 extension。 從代碼中可以看到, extension 是從 artifactHandler 而非 artifact 獲取 ,artifactHandler 是由項(xiàng)目的 packaging決定的。因此,可以說, packaging 決定了構(gòu)件的擴(kuò)展名,該例的 packaging 是 jar, 因此最終的路徑為org/testng/testng/5.8/testng-5.8-jdk5.jar。

到這里,應(yīng)該感謝Maven 開源社區(qū),正是由于Maven 的所有源代碼都是開放的,我們才能仔細(xì)地深入到其內(nèi)部工作的所有細(xì)節(jié)。
Maven 倉(cāng)庫(kù)是基于簡(jiǎn)單文件系統(tǒng)存儲(chǔ)的,我們也理解了其存儲(chǔ)方式,因此,當(dāng)遇到一些與倉(cāng)庫(kù)相關(guān)的問題時(shí),可以很方便地查找相關(guān)文件,方便定位問題。例如,當(dāng)Maven 無(wú)法獲得項(xiàng)目聲明的依賴時(shí),可以查看該依賴對(duì)應(yīng)的文件在倉(cāng)庫(kù)中是否存在,如果不存在, 查看是否有其他版本可用,等等。

3?? 倉(cāng)庫(kù)的分類

對(duì)于Maven 來(lái)說,倉(cāng)庫(kù)只分為兩類:本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)。當(dāng) Maven 根據(jù)坐標(biāo)尋找構(gòu)件的時(shí)候,它首先會(huì)查看本地倉(cāng)庫(kù),如果本地倉(cāng)庫(kù)存在此構(gòu)件,則直接使用;如果本地倉(cāng)庫(kù)不存在此構(gòu)件,或者需要查看是否有更新的構(gòu)件版本, Maven 就會(huì)去遠(yuǎn)程倉(cāng)庫(kù)查找,發(fā)現(xiàn)需要的構(gòu)件之后,下載到本地倉(cāng)庫(kù)再使用。如果本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)都沒有需要的構(gòu)件,Maven 就會(huì)報(bào)錯(cuò)。

在這個(gè)最基本分類的基礎(chǔ)上,還有必要介紹一些特殊的遠(yuǎn)程倉(cāng)庫(kù)。中央倉(cāng)庫(kù)是 Maven 核心自帶的遠(yuǎn)程倉(cāng)庫(kù),它包含了絕大部分開源的構(gòu)件。在默認(rèn)配置下,當(dāng)本地倉(cāng)庫(kù)沒有 Maven 需要的構(gòu)件的時(shí)候,它就會(huì)嘗試從中央倉(cāng)庫(kù)下載。

私服是另一種特殊的遠(yuǎn)程倉(cāng)庫(kù),為了節(jié)省帶寬和時(shí)間,應(yīng)該在局域網(wǎng)內(nèi)架設(shè)一個(gè)私有的倉(cāng)庫(kù)服務(wù)器,用其代理所有外部的遠(yuǎn)程倉(cāng)庫(kù)。內(nèi)部的項(xiàng)目還能部署到私服上供其他項(xiàng)目使用。

除了中央倉(cāng)庫(kù)和私服,還有很多其他公開的遠(yuǎn)程倉(cāng)庫(kù),常見的有Java.net Maven 庫(kù) (http://download.java.net/maven/2/)和 JBoss Maven 庫(kù)(http://neposiory.jloss. com/maven2/)等。Maven 倉(cāng)庫(kù)的分類見下圖。

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享

3.1 本地倉(cāng)庫(kù)

一般來(lái)說,在Maven 項(xiàng)目目錄下,沒有諸如 lib/這樣用來(lái)存放依賴文件的目錄。當(dāng) Maven 在執(zhí)行編譯或測(cè)試時(shí),如果需要使用依賴文件,它總是基于坐標(biāo)使用本地倉(cāng)庫(kù)的依賴文件。
默認(rèn)情況下,不管是在 Windows 還 是Linux 上,每個(gè)用戶在自己的用戶目錄下都有一個(gè)路徑名為,m2/repository/的倉(cāng)庫(kù)目錄。例如,我的用戶名是 xiaoshan, 我在 Windows 機(jī)器上 的本地倉(cāng)庫(kù)地址為 C:\Users\xiaoshan\.m2\repository\, 而我在Linux 上的本地倉(cāng)庫(kù)地址為 / home/xiaoshan/.m2/repository/。 注意,在Linux 系統(tǒng)中,以點(diǎn)( .)開頭的文件或目錄默認(rèn)是隱 藏的,可以使用 ls -a 命令顯示隱藏文件或目錄。

有時(shí)候,因?yàn)槟承┰?例如C 盤空間不夠),用戶會(huì)想要自定義本地倉(cāng)庫(kù)目錄地址。這時(shí),可以編輯文件~/.m2/ settings.xml, 設(shè)置 localRepository 元素的值為想要的倉(cāng)庫(kù)地址。例如:

<settings>
	<localRepository>D:\java\repository\</localRepository>
</settings>

這樣,該用戶的本地倉(cāng)庫(kù)地址就被設(shè)置成了 D:\java\repository\。
需要注意的是,默認(rèn)情況下,~/.m2/settings.xml 文件是不存在的,用戶需要從 Maven 安裝目錄復(fù)制 $MAVEN_HOME/conf/settings.xml 文件再進(jìn)行編輯。推薦大家不要直接修改全局目錄的 settings.xml文件。

一個(gè)構(gòu)件只有在本地倉(cāng)庫(kù)中之后,才能由其他 Maven 項(xiàng)目使用,那么構(gòu)件如何進(jìn)入到本地倉(cāng)庫(kù)中呢?最常見的是依賴Maven 從遠(yuǎn)程倉(cāng)庫(kù)下載到本地倉(cāng)庫(kù)中。還有一種常見的情況是,將本地項(xiàng)目的構(gòu)件安裝到 Maven 倉(cāng)庫(kù)中。例如,本地有兩個(gè)項(xiàng)目A 和 B, 兩者都無(wú)法從遠(yuǎn)程倉(cāng)庫(kù)獲得,而同時(shí)A 又依賴于B, 為了能構(gòu)建A,B 就必須首先得以構(gòu)建并安裝到本地倉(cāng)庫(kù)中。

在某個(gè)項(xiàng)目中執(zhí)行 mvn clean install命令,就能看到如下輸出:

[INFO][jar:jar {execution: default-jar}]
[INPO]          Building jar:D:\git-xiaoshan\maven-book\code\ch-5\account-email\target\account-emai1-1.0.0-SNAPSHOT.jar
[INFO][install:install {execution: default-install}]
[INFO]          Installing D:\git-xiaoshan\maven-book\code\ch-5\account-email\target\account-emai1-1.0.0-SNAPSHOT.jar to D:\java\repository\com\xiaoshan\mvnbook\account   account-emai1\1.0.0-SNAPSHOT\account-emai1-1.0.0-SNAPSHOT.jar
[INF0]
[INFO] BUILD SUCCESSFUL
[INFO]

Install 插件的 install 目標(biāo)將項(xiàng)目的構(gòu)建輸出文件安裝到本地倉(cāng)庫(kù)。在上述輸出中,構(gòu)建輸出文件是 account-email-1.0.0-SNAPSHOT. jar, 本地倉(cāng)庫(kù)地址是 D:\java\repository, Maven 使用Install 插件將該文件復(fù)制到本地倉(cāng)庫(kù)中,具體的路徑根據(jù)坐標(biāo)計(jì)算獲得。

3.2 遠(yuǎn)程倉(cāng)庫(kù)

安裝好Maven 后,如果不執(zhí)行任何 Maven 命令,本地倉(cāng)庫(kù)目錄是不存在的。當(dāng)用戶輸入第一條 Maven 命令之后, Maven 才會(huì)創(chuàng)建本地倉(cāng)庫(kù),然后根據(jù)配置和需要,從遠(yuǎn)程倉(cāng)庫(kù)下載構(gòu)件至本地倉(cāng)庫(kù)。

這好比藏書。例如,我想要讀《西游記》,會(huì)先檢查自己的書房是否已經(jīng)收藏了這本書,如果發(fā)現(xiàn)沒有這本書,于是就跑去書店買一本回來(lái),放到書房里??赡苡幸惶煳矣窒胱x一本英文版的《程序員修煉之道》,而書房里只有中文版,于是又去書店找,可發(fā)現(xiàn)書店沒有,好在還有網(wǎng)上書店,于是從Amazon 買了一本,幾天后我收到了這本書,又放到了自己的書房。

本地倉(cāng)庫(kù)就好比書房,我需要讀書的時(shí)候先從書房找,相應(yīng)地, Maven 需要構(gòu)件的時(shí)候先從本地倉(cāng)庫(kù)找。遠(yuǎn)程倉(cāng)庫(kù)就好比書店(包括實(shí)體書店、網(wǎng)上書店等), 當(dāng)我無(wú)法從自己的書房找到需要的書的時(shí)候,就會(huì)從書店購(gòu)買后放到書房里。當(dāng)Maven 無(wú)法從本地倉(cāng)庫(kù)找到需要的構(gòu)件的時(shí)候,就會(huì)從遠(yuǎn)程倉(cāng)庫(kù)下載構(gòu)件至本地倉(cāng)庫(kù)。 一般地,對(duì)于每個(gè)人來(lái)說,書房只有一個(gè),但外面的書店有很多,類似地,對(duì)于Maven 來(lái)說,每個(gè)用戶只有一個(gè)本地倉(cāng)庫(kù),但可以配置訪問很多遠(yuǎn)程倉(cāng)庫(kù)。

3.3 中央倉(cāng)庫(kù)

由于最原始的本地倉(cāng)庫(kù)是空的, Maven 必須知道至少一個(gè)可用的遠(yuǎn)程倉(cāng)庫(kù),才能在執(zhí)行 Maven 命令的時(shí)候下載到需要的構(gòu)件。中央倉(cāng)庫(kù)就是這樣一個(gè)默認(rèn)的遠(yuǎn)程倉(cāng)庫(kù), Maven 的安裝文件自帶了中央倉(cāng)庫(kù)的配置。讀者可以使用解壓工具打開 jar文件$MAVEN_HOME/lib/maven-model-builder-3.0.jar ( 在Maven 2中 ,jar文件路徑類似于$MAVEN_HOME/lib/maven-2.2.1-uber.jar), 然后訪問路徑 org/apache/maven/model/pom-4.0.0.xml, 可以看到如下的配置:

<repositories>
	<repository>
		<id>central</id>
		<name>Maven Repository Switchboard</name>
		<url>http://repol.maven.org/maven2</url>
		<layout>default</layout>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</repository>
</repositories>

包含這段配置的文件是所有Maven 項(xiàng)目都會(huì)繼承的超級(jí)POM, 后面文章會(huì)詳細(xì)介紹繼承及超級(jí) POM。 這段配置使用 id central對(duì)中央倉(cāng)庫(kù)進(jìn)行唯一標(biāo)識(shí),其名稱為 Maven Repository Switchboard, 它使用default倉(cāng)庫(kù)布局,對(duì)于Maven 1 的倉(cāng)庫(kù),需要配置值為 legacy 的 layout, 本書不會(huì)涉及 Maven 1。最后需要注意的是 snapshots 元素,其子元素 enabled 的 值為 false, 表示不從該中央倉(cāng)庫(kù)下載快照版本的構(gòu)件。

中央倉(cāng)庫(kù)包含了這個(gè)世界上絕大多數(shù)流行的開源 Java 構(gòu)件 , 以及源碼、作者信息、 SCM、信息、許可證信息等,每個(gè)月這里都會(huì)接受全世界Java 程序員大概 1 億次的訪問, 它對(duì)全世界Java 開發(fā)者的貢獻(xiàn)由此可見一斑。由于中央倉(cāng)庫(kù)包含了超過2000個(gè)開源項(xiàng)目的 構(gòu)件,因此一般來(lái)說, 一個(gè)簡(jiǎn)單 Maven 項(xiàng)目所需要的依賴構(gòu)件都能從中央倉(cāng)庫(kù)下載到。 這也解釋了為什么Maven 能做到“開箱即用”。

3.4 私服

私服是一種特殊的遠(yuǎn)程倉(cāng)庫(kù),它是架設(shè)在局域網(wǎng)內(nèi)的倉(cāng)庫(kù)服務(wù),私服代理廣域網(wǎng)上的遠(yuǎn)程倉(cāng)庫(kù),供局域網(wǎng)內(nèi)的 Maven 用戶使用。當(dāng)Maven 需要下載構(gòu)件的時(shí)候,它從私服請(qǐng)求, 如果私服上不存在該構(gòu)件,則從外部的遠(yuǎn)程倉(cāng)庫(kù)下載,緩存在私服上之后,再為 Maven 的 下載請(qǐng)求提供服務(wù)。此外, 一些無(wú)法從外部倉(cāng)庫(kù)下載到的構(gòu)件也能從本地上傳到私服上供 大家使用,如圖所示。

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享
圖示的是組織內(nèi)部使用私服的情況。即使在一臺(tái)直接連入Intemet 的個(gè)人機(jī)器上使用Maven, 也應(yīng)該在本地建立私服。因?yàn)樗椒梢詭椭悖?/p>

  • 節(jié)省自己的外網(wǎng)帶寬。 建立私服同樣可以減少組織自己的開支,大量的對(duì)于外部倉(cāng)庫(kù)的重復(fù)請(qǐng)求會(huì)消耗很大的帶寬,利用私服代理外部倉(cāng)庫(kù)之后,對(duì)外的重復(fù)構(gòu)件下載便得以消除,即降低外網(wǎng)帶寬的壓力。
  • 加速 Maven 構(gòu)建。不停地連接請(qǐng)求外部倉(cāng)庫(kù)是十分耗時(shí)的,但是Maven 的一些內(nèi)部機(jī)制(如快照更新檢查)要求Maven 在執(zhí)行構(gòu)建的時(shí)候不停地檢查遠(yuǎn)程倉(cāng)庫(kù)數(shù)據(jù)。 因此,當(dāng)項(xiàng)目配置了很多外部遠(yuǎn)程倉(cāng)庫(kù)的時(shí)候,構(gòu)建的速度會(huì)被大大降低。使用私服可以很好地解決這一 問題,當(dāng) Maven 只需要檢查局域網(wǎng)內(nèi)私服的數(shù)據(jù)時(shí),構(gòu)建的速度便能得到很大程度的提高。
  • 部署第三方構(gòu)件。當(dāng)某個(gè)構(gòu)件無(wú)法從任何一個(gè)外部遠(yuǎn)程倉(cāng)庫(kù)獲得,怎么辦? 這樣的例子有很多,如組織內(nèi)部生成的私有構(gòu)件肯定無(wú)法從外部倉(cāng)庫(kù)獲得、 Oracle 的 JDBC 驅(qū)動(dòng)由于版權(quán)因素不能發(fā)布到公共倉(cāng)庫(kù)中。建立私服之后,便可以將這些構(gòu)件部署到這個(gè)內(nèi)部的倉(cāng)庫(kù)中,供內(nèi)部的Maven 項(xiàng)目使用。
  • 提高穩(wěn)定性,增強(qiáng)控制。 Maven 構(gòu)建高度依賴于遠(yuǎn)程倉(cāng)庫(kù),因此,當(dāng) Intemet 不穩(wěn)定的時(shí)候, Maven 構(gòu)建也會(huì)變得不穩(wěn)定,甚至無(wú)法構(gòu)建。使用私服后,即使暫時(shí)沒有 Internet 連接,由于私服中已經(jīng)緩存了大量構(gòu)件, Maven 也仍然可以正常運(yùn)行。此外, 一些私服軟 件 ( 如 Nexus) 還提供了很多額外的功能,如權(quán)限管理、 RELEASE/SNAPSHOT 區(qū)分等,管理員可以對(duì)倉(cāng)庫(kù)進(jìn)行一些更高級(jí)的控制。
  • 降低中央倉(cāng)庫(kù)的負(fù)荷。運(yùn)行并維護(hù)一個(gè)中央倉(cāng)庫(kù)不是一件容易的事情,服務(wù)數(shù)百萬(wàn)的請(qǐng)求,存儲(chǔ)數(shù)T 的數(shù)據(jù),需要相當(dāng)大的財(cái)力。使用私服可以避免很多對(duì)中央倉(cāng)庫(kù)重復(fù)的下載,想象一下, 一個(gè)有數(shù)百位開發(fā)人員的公司,在不使用私服的情況下, 一個(gè)構(gòu)件往往會(huì)被重復(fù)下載數(shù)百次;建立私服之后,這幾百次下載就只會(huì)發(fā)生在內(nèi)網(wǎng)范圍內(nèi),私服對(duì)于中央倉(cāng)庫(kù)只有一次下載。

建立私服是用好Maven 十分關(guān)鍵的一步,后面我會(huì)專門介紹如何使用最流行的 Maven 私服軟件——Nexus。

4?? 遠(yuǎn)程倉(cāng)庫(kù)的配置

在很多情況下,默認(rèn)的中央倉(cāng)庫(kù)無(wú)法滿足項(xiàng)目的需求,可能項(xiàng)目需要的構(gòu)件存在于另外一個(gè)遠(yuǎn)程倉(cāng)庫(kù)中,如JBoss Maven 倉(cāng)庫(kù)。這時(shí),可以在 POM 中配置該倉(cāng)庫(kù),代碼如下。

<project>
	<repositories>
		<repository>
			<id>jboss</id>
			<name>JBoss Repository</name>
			<url>http://repository.jboss.com/maven2/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
			<layout>default</layout>
		</repository>
	</repositories>
</project>

repositories元素下,可以使用 repository 子元素聲明一個(gè)或者多個(gè)遠(yuǎn)程倉(cāng)庫(kù)。該例中聲明了一個(gè)id 為 jboss, 名稱為JBoss Repository的倉(cāng)庫(kù)。任何一個(gè)倉(cāng)庫(kù)聲明的id 必須是唯一的,尤其需要注意的是, Maven 自帶的中央倉(cāng)庫(kù)使用的 id 為 central, 如果其他的倉(cāng)庫(kù)聲明 也使用該 id, 就會(huì)覆蓋中央倉(cāng)庫(kù)的配置。該配置中的url值指向了倉(cāng)庫(kù)的地址,一般來(lái)說, 該地址都基于http 協(xié)議, Maven 用戶都可以在瀏覽器中打開倉(cāng)庫(kù)地址瀏覽構(gòu)件。

該例配置中的 releases 和 snapshots元素比較重要,它們用來(lái)控制 Maven 對(duì)于發(fā)布版構(gòu)件 和快照版構(gòu)件的下載。關(guān)于快照版本,在后文中會(huì)詳細(xì)解釋。這里需要注意的是 enabled子元素,該例中releases 的 enabled 值 為true, 表示開啟JBoss 倉(cāng)庫(kù)的發(fā)布版本下載支持, 而snapshots 的 enabled 值 為false, 表示關(guān)閉JBoss 倉(cāng)庫(kù)的快照版本的下載支持。因此,根據(jù) 該配置, Maven 只會(huì)從 JBoss倉(cāng)庫(kù)下載發(fā)布版的構(gòu)件,而不會(huì)下載快照版的構(gòu)件。

該例中的 layout 元素值 default表示倉(cāng)庫(kù)的布局是 Maven 2 及 Maven 3 的默認(rèn)布局,而不 是 Maven 1的布局。
對(duì)于 releases 和 snapshots 來(lái)說,除了 enabled, 它們還包含另外兩個(gè)子元素 updatePolicy 和 checksumPolicy:

<snapshots>
	<enabled>true</enabled>
	<updatePolicy>daily</updatePolicy>
	<checksumPolicy>ignore</checksumPolicy>
</snapshots>

元素 updatePolicy 用來(lái)配置 Maven 從遠(yuǎn)程倉(cāng)庫(kù)檢查更新的頻率,默認(rèn)的值是 daily, 表 示 Maven 每天檢查一次。其他可用的值包括: never—從不檢查更新; always—每次構(gòu)建都檢查更新 ;interval:X— 每隔X 分鐘檢查一次更新(X 為任意整數(shù))。

元素 checksumPolicy 用來(lái)配置 Maven 檢查檢驗(yàn)和文件的策略。當(dāng)構(gòu)件被部署到 Maven 倉(cāng) 庫(kù)中時(shí),會(huì)同時(shí)部署對(duì)應(yīng)的校驗(yàn)和文件。在下載構(gòu)件的時(shí)候, Maven 會(huì)驗(yàn)證校驗(yàn)和文件, 如果校驗(yàn)和驗(yàn)證失敗,怎么辦? 當(dāng) checksumPolicy的值為默認(rèn)的warn 時(shí) ,Maven 會(huì)在執(zhí)行構(gòu)建時(shí)輸出警告信息,其他可用的值包括: fail—Maven 遇到校驗(yàn)和錯(cuò)誤就讓構(gòu)建失??;ignore—使 Maven 完全忽略校驗(yàn)和錯(cuò)誤。

4.1 遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證

大部分遠(yuǎn)程倉(cāng)庫(kù)無(wú)須認(rèn)證就可以訪問,但有時(shí)候出于安全方面的考慮,我們需要提供認(rèn)證信息才能訪問一些遠(yuǎn)程倉(cāng)庫(kù)。例如,組織內(nèi)部有一個(gè)Maven 倉(cāng)庫(kù)服務(wù)器,該服務(wù)器為每個(gè)項(xiàng)目都提供獨(dú)立的Maven 倉(cāng)庫(kù),為了防止非法的倉(cāng)庫(kù)訪問,管理員為每個(gè)倉(cāng)庫(kù)提供了一組用戶名及密碼。這時(shí),為了能讓 Maven 訪問倉(cāng)庫(kù)內(nèi)容,就需要配置認(rèn)證信息。

配置認(rèn)證信息和配置倉(cāng)庫(kù)信息不同,倉(cāng)庫(kù)信息可以直接配置在POM文件中,但是認(rèn)證信息必須配置在settings.xml文件中。這是因?yàn)镻OM往往是被提交到代碼倉(cāng)庫(kù)中供所有成員訪問的,而settings.xml一般只放在本機(jī)。因此,在settings.xml中配置認(rèn)證信息更為安全。

假設(shè)需要為一個(gè)id為 my-proj的倉(cāng)庫(kù)配置認(rèn)證信息,編輯settings.xml文件見代碼:

<settings>
	<servers>
		<server>
			<id>my-proj</id>
			<username>repo-user</username>
			<password>repo-pwd</password>
		</server>
	</servers>
</settings>

Maven使用settings.xml文件中并不顯而易見的 servers元素及其server子元素配置倉(cāng)庫(kù)認(rèn)證信息。代碼中該倉(cāng)庫(kù)的認(rèn)證用戶名為 repo-user,認(rèn)證密碼為 repo-pwd。這里的關(guān)鍵是id元素,settings.xml中server元素的 id必須與POM中需要認(rèn)證的repository元素的id完全一致。換句話說,正是這個(gè)id將認(rèn)證信息與倉(cāng)庫(kù)配置聯(lián)系在了一起。

4.2 部署至遠(yuǎn)程倉(cāng)庫(kù)

在前文中提到,私服的一大作用是部署第三方構(gòu)件,包括組織內(nèi)部生成的構(gòu)件以及一些無(wú)法從外部倉(cāng)庫(kù)直接獲取的構(gòu)件。無(wú)論是日常開發(fā)中生成的構(gòu)件,還是正式版本發(fā)布的構(gòu)件,都需要部署到倉(cāng)庫(kù)中,供其他團(tuán)隊(duì)成員使用。

Maven除了能對(duì)項(xiàng)目進(jìn)行編譯、測(cè)試、打包之外,還能將項(xiàng)目生成的構(gòu)建部署到倉(cāng)庫(kù)中。

首先,需要編輯項(xiàng)目的 pom.xml文件。配置 distributionManagement 元素見代碼:

<project>
	<distributionManagement>
		<repository>
			<id>proj-releases</id>
			<name>Proj Release Repository</name>
			<url>http://192.168.1.100/content/repositories/proj-releases</url>
		</repository>
		<snapshotRepository>
			<id>proj-snapshots</id>
			<name>Proj Snapshot Repository</name>
			<url>http://192.168.1.100/content/repositories/proj-snapshots</url>
		</snapshotRepository>
	</distributionManagement>
</project>

distributionManagement 包含 repository 和 snapshotRepository 子元素,前者表示發(fā)布版本構(gòu)件的倉(cāng)庫(kù),后者表示快照版本的倉(cāng)庫(kù)。關(guān)于發(fā)布版本和快照版本,后文會(huì)詳細(xì)解釋。 這兩個(gè)元素下都需要配置 id、name 和 url, id 為該遠(yuǎn)程倉(cāng)庫(kù)的唯一標(biāo)識(shí), name 是為了方便人閱讀,關(guān)鍵的url表示該倉(cāng)庫(kù)的地址。

往遠(yuǎn)程倉(cāng)庫(kù)部署構(gòu)件的時(shí)候,往往需要認(rèn)證。配置認(rèn)證的方式已詳細(xì)闡述,簡(jiǎn)而言之,就是需要在settings.xml中創(chuàng)建一個(gè) server元素,其id 與倉(cāng)庫(kù)的id 匹配 , 配置正確的認(rèn)證信息。不論從遠(yuǎn)程倉(cāng)庫(kù)下載構(gòu)件,還是部署構(gòu)件至遠(yuǎn)程倉(cāng)庫(kù),當(dāng)需要認(rèn)證的時(shí)候,配置的方式是 一樣的。

配置正確后,在命令行運(yùn)行 mvn clean deploy, Maven 就會(huì)將項(xiàng)目構(gòu)建輸出的構(gòu)件部署到配置對(duì)應(yīng)的遠(yuǎn)程倉(cāng)庫(kù),如果項(xiàng)目當(dāng)前的版本是快照版本,則部署到快照版本倉(cāng)庫(kù)地址, 否則就部署到發(fā)布版本倉(cāng)庫(kù)地址。如下是部署一個(gè)快照版本的輸出:

[INF0]---maven-deploy-plugin:2.4:deploy (default-deploy) account-email           ---
[INFO]     Retrieving previous build number from proj-snapshots
Uploading:
http:// 192.168.1.100/content/repositories/proj-snapshots/com/xiaoshan/mvnbook/account/account-emai1/1.0.0-SNAPSHOT/account-emai1-1.0.0-20230903.150936-2.jar
6 KB uploaded at 727.8 KB/sec
[INFO]      Retrieving previous metadata from proj-snapshots
[INPO]        Uploading repository metadata for:'artifact        com.xiaoshan.mvnbook.account:account-email!
[INFO]       Uploading project information for account-email1.0.0-20230903.150936-2
[INFO]      Retrieving previous metadata from proj-snapshots
[INFo]        Uploading repository metadata for:'snapshot        com.xiaoshan.mvnbook,account:ac- count-email:1.0.0-SNAPSHOT'
[INFO]
[INFO] BUILD SUCCESS
[INFO]

5?? 快照版本

在Maven的世界中,任何一個(gè)項(xiàng)目或者構(gòu)件都必須有自己的版本。版本的值可能是 1.0.0、1.3-alpha-4、2.0、2.1-SNAPSHOT 或者 2.1-20091214.221414-13。其中,1.0.0、1.3-alpha-4和2.0是穩(wěn)定的發(fā)布版本,而2.1-SNAPSHOT和2.1-20091214.221414-13是不穩(wěn)定的快照版本。

Maven為什么要區(qū)分發(fā)布版和快照版呢? 簡(jiǎn)單的1.0.0、1.2、2.1等不就夠了嗎? 為什么還要有2.1-SNAPSHOT, 甚至是長(zhǎng)長(zhǎng)的 2.1-20091214.221414-13? 試想一下這樣的情況,小張?jiān)陂_發(fā)模塊A的2.1版本,該版本還未正式發(fā)布,與模塊A一同開發(fā)的還有模塊B,它由小張的同事季MM開發(fā),B的功能依賴于A。在開發(fā)的過程中,小張需要經(jīng)常將自己最新的構(gòu)建輸出,交給季MM, 供她開發(fā)和集成調(diào)試,問題是,這個(gè)工作如何進(jìn)行呢?

  1. 方案一
    讓季MM 自己遷出模塊A 的源碼進(jìn)行構(gòu)建。這種方法能夠確保季 MM 得到模塊A 的最新構(gòu)件,不過她不得不去構(gòu)建模塊A。 多了一些版本控制和 Maven 操作還不算,當(dāng)構(gòu)建A 失敗的時(shí)候,她會(huì)是一頭霧水,最后不得不找小張解決。顯然,這種方式是低效的。

  2. 方案二
    重復(fù)部署模塊A 的2.1版本供季MM 下載。雖然小張能夠保證倉(cāng)庫(kù)中的構(gòu)件是最新的, 但對(duì)于Maven 來(lái)說,同樣的版本和同樣的坐標(biāo)就意味著同樣的構(gòu)件。因此,如果季 MM 在本機(jī)的本地倉(cāng)庫(kù)包含了模塊A 的 2.1版本構(gòu)件, Maven 就不會(huì)再對(duì)照遠(yuǎn)程倉(cāng)庫(kù)進(jìn)行更新。除非她每次執(zhí)行Maven 命令之前,清除本地倉(cāng)庫(kù),但這種要求手工干預(yù)的做法顯然也是不可取的。

  3. 方案三
    不停更新版本2.1.1、2.1.2、2.1.3…… 。首先,小張和季MM 兩人都需要頻繁地更改 POM, 如果有更多的模塊依賴于模塊A, 就會(huì)涉及更多的POM 更改;其次,大量的版本其實(shí)僅僅包含了微小的差異,有時(shí)候是對(duì)版本號(hào)的濫用。

Maven 的快照版本機(jī)制就是為了解決上述問題。在該例中,小張只需要將模塊A 的版本設(shè)定為2.1-SNAPSHOT, 然后發(fā)布到私服中,在發(fā)布的過程中, Maven 會(huì)自動(dòng)為構(gòu)件打上時(shí)間戳。比如 2.1-20221214.221414-13 就表示 2022年12月14日22點(diǎn)14分14秒的第13次快照。有了該時(shí)間戳, Maven 就能隨時(shí)找到倉(cāng)庫(kù)中該構(gòu)件2.1-SNAPSHOT 版本最新的文件。 這時(shí),季MM 配置對(duì)于模塊A 的 2.1-SNAPSHOT 版本的依賴,當(dāng)她構(gòu)建模塊B 的時(shí)候, Maven會(huì)自動(dòng)從倉(cāng)庫(kù)中檢查模塊A 的 2.1-SNAPSHOT 的最新構(gòu)件,當(dāng)發(fā)現(xiàn)有更新時(shí)便進(jìn)行下載。默認(rèn)情況下, Maven 每天檢查一次更新(由倉(cāng)庫(kù)配置的 updatePolicy 控制,見第6.4 節(jié)),用戶也可以使用命令行-U 參數(shù)強(qiáng)制讓 Maven 檢查更新,如 mvn clean install -U

基于快照版本機(jī)制,小張?jiān)跇?gòu)建成功之后才能將構(gòu)件部署至倉(cāng)庫(kù),而季 MM 可以完全不用考慮模塊A 的構(gòu)建,并且她能確保隨時(shí)得到模塊A 的最新可用的快照構(gòu)件,而這一切都不需要額外的手工操作。

當(dāng)項(xiàng)目經(jīng)過完善的測(cè)試后需要發(fā)布的時(shí)候,就應(yīng)該將快照版本更改為發(fā)布版本。例如, 將2.1-SNAPSHOT 更改為2.1,表示該版本已經(jīng)穩(wěn)定,且只對(duì)應(yīng)了唯一的構(gòu)件。相比之下, 2.1-SNAPSHOT 往往對(duì)應(yīng)了大量的帶有不同時(shí)間戳的構(gòu)件,這也決定了其不穩(wěn)定性。

快照版本只應(yīng)該在組織內(nèi)部的項(xiàng)目或模塊間依賴使用,因?yàn)檫@時(shí),組織對(duì)于這些快照版本的依賴具有完全的理解及控制權(quán)。項(xiàng)目不應(yīng)該依賴于任何組織外部的快照版本依賴, 由于快照版本的不穩(wěn)定性,這樣的依賴會(huì)造成潛在的危險(xiǎn)。也就是說,即使項(xiàng)目構(gòu)建今天是成功的,由于外部的快照版本依賴實(shí)際對(duì)應(yīng)的構(gòu)件隨時(shí)可能變化,項(xiàng)目的構(gòu)建就可能由于這些外部的不受控制的因素而失敗。

6?? 從倉(cāng)庫(kù)解析依賴的機(jī)制

前面的文章中詳細(xì)介紹了Maven 的依賴機(jī)制,本章又深入闡述了Maven 倉(cāng)庫(kù),這兩者是如何 具體聯(lián)系到一起的呢? Maven 是根據(jù)怎樣的規(guī)則從倉(cāng)庫(kù)解析并使用依賴構(gòu)件的呢?

當(dāng)本地倉(cāng)庫(kù)沒有依賴構(gòu)件的時(shí)候, Maven 會(huì)自動(dòng)從遠(yuǎn)程倉(cāng)庫(kù)下載;當(dāng)依賴版本為快照版本的時(shí)候, Maven 會(huì)自動(dòng)找到最新的快照。這背后的依賴解析機(jī)制可以概括如下:

(1)當(dāng)依賴的范圍是 system的 時(shí)候 ,Maven 直接從本地文件系統(tǒng)解析構(gòu)件。
(2)根據(jù)依賴坐標(biāo)計(jì)算倉(cāng)庫(kù)路徑后,嘗試直接從本地倉(cāng)庫(kù)尋找構(gòu)件,如果發(fā)現(xiàn)相應(yīng)構(gòu)件,則解析成功。
(3)在本地倉(cāng)庫(kù)不存在相應(yīng)構(gòu)件的情況下,如果依賴的版本是顯式的發(fā)布版本構(gòu)件,如 1.2、2.1-beta-1等,則遍歷所有的遠(yuǎn)程倉(cāng)庫(kù),發(fā)現(xiàn)后,下載并解析使用。
(4)如果依賴的版本是 RELEASE 或者 LATEST, 則基于更新策略讀取所有遠(yuǎn)程倉(cāng)庫(kù)的元數(shù)據(jù) groupId/artifactId/maven-metadata.xml,將其與本地倉(cāng)庫(kù)的對(duì)應(yīng)元數(shù)據(jù)合并后,計(jì)算出 RELEASE 或者 LATEST 真實(shí)的值,然后基于這個(gè)真實(shí)的值檢查本地和遠(yuǎn)程倉(cāng)庫(kù),如步驟2和3。
(5)如果依賴的版本是 SNAPSHOT, 則基于更新策略讀取所有遠(yuǎn)程倉(cāng)庫(kù)的元數(shù)據(jù)
groupId/artifactId/version/maven-metadata.xml, 將其與本地倉(cāng)庫(kù)的對(duì)應(yīng)元數(shù)據(jù)合并后,得到 最新快照版本的值,然后基于該值檢查本地倉(cāng)庫(kù),或者從遠(yuǎn)程倉(cāng)庫(kù)下載。
(6)如果最后解析得到的構(gòu)件版本是時(shí)間戳格式的快照,如1.4.1-20091104.121450-121,
則復(fù)制其時(shí)間戳格式的文件至非時(shí)間戳格式,如 SNAPSHOT, 并使用該非時(shí)間戳格式的構(gòu)件。

當(dāng)依賴的版本不明晰的時(shí)候,如 RELEASE、LATEST 和 SNAPSHOT, Maven 就需要基于更新遠(yuǎn)程倉(cāng)庫(kù)的更新策略來(lái)檢查更新。在第前面提到的倉(cāng)庫(kù)配置中,有一些配置與此有關(guān):首先是 <releases><enabled><snapshots><enabled>, 只有倉(cāng)庫(kù)開啟了對(duì)于發(fā)布版本的支持時(shí),才能訪問該倉(cāng)庫(kù)的發(fā)布版本構(gòu)件信息,對(duì)于快照版本也是同理;其次要注意的是 <releases><snapshots> 的子元素<updatePolicy>, 該元素配置了檢查更新的頻率,每日 檢查更新、永遠(yuǎn)檢查更新、從不檢查更新、自定義時(shí)間間隔檢查更新等。最后,用戶還可以 從命令行加入?yún)?shù) -U, 強(qiáng)制檢查更新,使用參數(shù)后, Maven 就會(huì)忽略<updatePolicy> 的配置。

當(dāng) Maven 檢查完更新策略,并決定檢查依賴更新的時(shí)候,就需要檢查倉(cāng)庫(kù)元數(shù)據(jù) maven-metadata. xml。
回顧一下前面提到的 RELEASE 和 LATEST 版本,它們分別對(duì)應(yīng)了倉(cāng)庫(kù)中存在的該構(gòu)件 的最新發(fā)布版本和最新版本(包含快照), 而這兩個(gè)“最新”是基于 groupId/artifactId/maven-metadata.xml 計(jì)算出來(lái)的,見代碼:

<?xml version="1.0"encoding="UTP-8"?>
<metadata>
	<groupId>org.sonatype.nexus</groupId>
	<artifactId>nexus</artifactId>
	<versioning>
		<latest>1.4.2-SNAPSHOT</latest>
		<release>1.4.0</release>
		<versions>
			<version>1.3.5</version>
			<version>1.3.6</version>
			<version>1.4.0-SNAPSHOT</version>
			<version>1.4.0</version>
			<version> 1.4.0.1-SNAPSHOT</version>
			<version>1.4.1-SNAPSHOT</version>
			<version>1.4.2-SNAPSHOT</version>
		</versions>
		<lastUpdated>20091214221557</lastUpdated>
	</versioning>
</metadata>

該 XML 文件列出了倉(cāng)庫(kù)中存在的該構(gòu)件所有可用的版本,同時(shí) latest元素指向了這些版本中最新的那個(gè)版本,該例中是 1.4.2-SNAPSHOT。而release元素指向了這些版本中最新的發(fā)布版本,該例中是1.4.0。Maven通過合并多個(gè)遠(yuǎn)程倉(cāng)庫(kù)及本地倉(cāng)庫(kù)的元數(shù)據(jù),就能計(jì)算出基于所有倉(cāng)庫(kù)的 latestrelease分別是什么,然后再解析具體的構(gòu)件。

需要注意的是,在依賴聲明中使用 LATEST和 RELEASE是不推薦的做法,因?yàn)镸aven隨時(shí)都可能解析到不同的構(gòu)件,可能今天 LATEST是1.3.6,明天就成為 1.4.0-SNAPSHOT了,且Maven不會(huì)明確告訴用戶這樣的變化。當(dāng)這種變化造成構(gòu)建失敗的時(shí)候,發(fā)現(xiàn)問題會(huì)變得比較困難。RELEASE因?yàn)閷?duì)應(yīng)的是最新發(fā)布版構(gòu)建,還相對(duì)可靠,LATEST就非常不可靠了,為此,Maven3不再支持在插件配置中使用 LATEST和 RELEASE。如果不設(shè)置插件版本,其效果就和 RELEASE一樣,Maven只會(huì)解析最新的發(fā)布版本構(gòu)件。不過即使這樣,也還存在潛在的問題。例如,某個(gè)依賴的1.1版本與1.2版本可能發(fā)生一些接口的變化,從而導(dǎo)致當(dāng)前Maven構(gòu)建的失敗。當(dāng)依賴的版本設(shè)為快照版本的時(shí)候,Maven也需要檢查更新,這時(shí),Maven會(huì)檢查倉(cāng)庫(kù)元數(shù)據(jù) groupId/artifactId/version/maven-metadata.xml,見代碼:

<?xml version="1.0"encoding="UTF-8*?>
<metadata>
	<groupId>org.sonatype.nexus</groupId>
	<artifactId>nexus</artifactId>
	<version>1.4.2-SNAPSHOT</version>
	<versioning>
		<snapshot>
			<timestamp>20091214.221414</timestamp>
			<buildNumber>13</buildNumber>
		</snapshot>
		<lastUpdated>20091214221558</lastUpdated>
	</versioning>
</metadata>

該XML文件的 snapshot元素包含了 timestampbuildNumber 兩個(gè)子元素,分別代表了這一快照的時(shí)間戳和構(gòu)建號(hào),基于這兩個(gè)元素可以得到該倉(cāng)庫(kù)中此快照的最新構(gòu)件版本實(shí)際為1.4.2-20091214.221414-13。通過合并所有遠(yuǎn)程倉(cāng)庫(kù)和本地倉(cāng)庫(kù)的元數(shù)據(jù),Maven就能知道所有倉(cāng)庫(kù)中該構(gòu)件的最新快照。

最后,倉(cāng)庫(kù)元數(shù)據(jù)并不是永遠(yuǎn)正確的,有時(shí)候當(dāng)用戶發(fā)現(xiàn)無(wú)法解析某些構(gòu)件,或者解析得到錯(cuò)誤構(gòu)件的時(shí)候,就有可能是出現(xiàn)了倉(cāng)庫(kù)元數(shù)據(jù)錯(cuò)誤,這時(shí)就需要手工地,或者使用工具 ( 如Nexus) 對(duì)其進(jìn)行修復(fù)。

7?? 鏡像

如果倉(cāng)庫(kù)X 可以提供倉(cāng)庫(kù)Y 存儲(chǔ)的所有內(nèi)容,那么就可以認(rèn)為X 是 Y 的一個(gè)鏡像。換句話說,任何一個(gè)可以從倉(cāng)庫(kù)Y 獲得的構(gòu)件,都能夠從它的鏡像中獲取。舉個(gè)例子, http://maven.net.cn/content/groups/public/ 是中央倉(cāng)庫(kù) http://repol.maven.org/maven2/ 在中國(guó)的鏡像,由于地理位置的因素,該鏡像往往能夠提供比中央倉(cāng)庫(kù)更快的服務(wù)。因此,可以配置Maven 使用該鏡像來(lái)替代中央倉(cāng)庫(kù)。編輯 settings.xml, 見代碼:

<settings>
	<mirrors>
		<mirror>
			<id>maven.net.cn</id>
			<name>one of the central mirrors in China</name>
			<url>http://maven.net.cn/content/groups/public/</url>
			<mirrorof>central</mirrorof>
		</mirror>
	</mirrors>
</settings>

該例中, <mirrorof> 的值為central, 表示該配置為中央倉(cāng)庫(kù)的鏡像,任何對(duì)于中央倉(cāng)庫(kù)的請(qǐng)求都會(huì)轉(zhuǎn)至該鏡像,用戶也可以使用同樣的方法配置其他倉(cāng)庫(kù)的鏡像。另外三個(gè)元素 id、name、url 與一般倉(cāng)庫(kù)配置無(wú)異,表示該鏡像倉(cāng)庫(kù)的唯一標(biāo)識(shí)符、名稱以及地址。類似地,如果該鏡像需要認(rèn)證,也可以基于該id 配置倉(cāng)庫(kù)認(rèn)證。

關(guān)于鏡像的一個(gè)更為常見的用法是結(jié)合私服。由于私服可以代理任何外部的公共倉(cāng)庫(kù) (包括中央倉(cāng)庫(kù)), 因此,對(duì)于組織內(nèi)部的 Maven 用戶來(lái)說,使用一個(gè)私服地址就等于使用了所有需要的外部倉(cāng)庫(kù),這可以將配置集中到私服,從而簡(jiǎn)化 Maven 本身的配置。在這種情況下,任何需要的構(gòu)件都可以從私服獲得,私服就是所有倉(cāng)庫(kù)的鏡像。這時(shí),可以配置這樣的 一個(gè)鏡像,見代碼:

<settings>
	<mirrors>
		<mirror>
			<id>internalrepository</id>
			<name>Internal Repository Manager</name>
			<url>http:// 192.168.1.100/maven2/</url>
			<mirrorof>*</mirrorof>
		</mirror>
	</mirrors>
</settings>

該例中 <mirrorof> 的值為星號(hào),表示該配置是所有Maven 倉(cāng)庫(kù)的鏡像,任何對(duì)于遠(yuǎn)程倉(cāng)庫(kù)的請(qǐng)求都會(huì)被轉(zhuǎn)至 http://192.168.1.100/maven2/。 如果該鏡像倉(cāng)庫(kù)需要認(rèn)證,則配置一個(gè) id為 intenal-repository<server> 即可。

為了滿足一些復(fù)雜的需求, Maven 還支持更高級(jí)的鏡像配置:

  • <mirrorOf>*</mirrorOf>: 匹配所有遠(yuǎn)程倉(cāng)庫(kù)。
  • <mirrorOf>external:*</mirrorOf>: 匹配所有遠(yuǎn)程倉(cāng)庫(kù),使用 localhost 的除外,使用 file:// 協(xié)議的除外。也就是說,匹配所有不在本機(jī)上的遠(yuǎn)程倉(cāng)庫(kù)。
  • <mirrorOf>repo1,repo2</mirrorOf>: 匹配倉(cāng)庫(kù) repo1repo2, 使用逗號(hào)分隔多個(gè)遠(yuǎn)程倉(cāng)庫(kù)。
  • <mirrorOf>*,!repo1</mirrorOf>: 匹配所有遠(yuǎn)程倉(cāng)庫(kù),repo1 除外,使用感嘆號(hào)將倉(cāng)庫(kù)從匹配中排除。

需要注意的是,由于鏡像倉(cāng)庫(kù)完全屏蔽了被鏡像倉(cāng)庫(kù),當(dāng)鏡像倉(cāng)庫(kù)不穩(wěn)定或者停止服務(wù)的時(shí)候, Maven 仍將無(wú)法訪問被鏡像倉(cāng)庫(kù),因而將無(wú)法下載構(gòu)件。

8?? 倉(cāng)庫(kù)搜索服務(wù)

使用Maven 進(jìn)行日常開發(fā)的時(shí)候, 一個(gè)常見的問題就是如何尋找需要的依賴,我們可能只知道需要使用類庫(kù)的項(xiàng)目名稱,但添加 Maven 依賴要求提供確切的Maven 坐標(biāo)。這時(shí), 就可以使用倉(cāng)庫(kù)搜索服務(wù)來(lái)根據(jù)關(guān)鍵字得到 Maven 坐標(biāo)。本節(jié)介紹幾個(gè)常用的、功能強(qiáng)大 的公共Maven 倉(cāng)庫(kù)搜索服務(wù)。

8.1 Sonatype Nexus

地址 :http://repository.sonatype.org/
Nexus 是當(dāng)前最流行的開源Maven 倉(cāng)庫(kù)管理軟件,后面會(huì)有專門的文章講述如何使用 Nexus 假設(shè)私服。這里要介紹的是Sonatype架設(shè)的一個(gè)公共Nexus 倉(cāng)庫(kù)實(shí)例。

Nexus 提供了關(guān)鍵字搜索、類名搜索、坐標(biāo)搜索、校驗(yàn)和搜索等功能。搜索后,頁(yè)面清晰地列出了結(jié)果構(gòu)件的坐標(biāo)及所屬倉(cāng)庫(kù)。用戶可以直接下載相應(yīng)構(gòu)件,還可以直接復(fù)制已經(jīng)根據(jù)坐標(biāo)自動(dòng)生成的XML 依賴聲明,見下圖。

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享


8.2 Jarvana

地址: http://www.jarvana.com/jarvana/
Jarvana提供了基于關(guān)鍵字、類名的搜索,構(gòu)件下載、依賴聲明片段等功能也一應(yīng)俱全。 值得一提的是, Jarvana還支持瀏覽構(gòu)件內(nèi)部的內(nèi)容。此外, Jarvana 還提供了便捷的 Java文檔瀏覽的功能。

8.3 MVNbrowser

地址: http://www.mvnbrowser.com
MVNbrowser 只提供關(guān)鍵字搜索的功能,除了提供基于坐標(biāo)的依賴聲明代碼片段等基本功能之外, MVNbrowser 的一大特色就是,能夠告訴用戶該構(gòu)件的依賴于其他哪些構(gòu)件 (Dependencies) 以及該構(gòu)件被哪些其他構(gòu)件依賴 (Referenced By)。

8.4 MVNrepository

地址:http://mvnrepository.com/
MVNrepository 的界面比較清新,它提供了基于關(guān)鍵字的搜索、依賴聲明代碼片段、構(gòu)件下載、依賴與被依賴關(guān)系信息、構(gòu)件所含包信息等功能。 MVNrepository 還能提供一個(gè)簡(jiǎn)單的圖表,顯示某個(gè)構(gòu)件各版本間的大小變化。 MVNrepository 的頁(yè)面如圖所示。

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享

上述介紹的四個(gè)倉(cāng)庫(kù)搜索服務(wù)都代理了主流的Maven 公共倉(cāng)庫(kù),如 central、JBoss、Java.net 等。這些服務(wù)都提供了完備的搜索、瀏覽、下載等功能,區(qū)別只在于頁(yè)面風(fēng)格和額 外功能。例如, Nexus 提供了其他三種服務(wù)所沒有的基于校驗(yàn)和搜索的功能。用戶可以根據(jù) 喜好和特殊需要選擇最合適自己的搜索服務(wù),當(dāng)然,也可以綜合使用所有這些服務(wù)。

?? 總結(jié)

本文深入闡述了倉(cāng)庫(kù)這一Maven 核心概念。首先介紹了倉(cāng)庫(kù)的由來(lái);接著直接剖析了一段 Maven 源碼,介紹倉(cāng)庫(kù)的布局,以方便讀者將倉(cāng)庫(kù)與實(shí)際文件聯(lián)系起來(lái);而倉(cāng)庫(kù)的分類這一部分則分別介紹了本地倉(cāng)庫(kù)、遠(yuǎn)程倉(cāng)庫(kù)、中央倉(cāng)庫(kù)以及私服等概念;基于這些概念, 又詳細(xì)介紹了倉(cāng)庫(kù)的配置;在此基礎(chǔ)上,我們?cè)偕钊雮}(cāng)庫(kù)的內(nèi)部工作機(jī)制,并同時(shí)解釋了 Maven 中快照的概念。還解釋了鏡像的概念及用法。最后,本章介紹了一些常用的倉(cāng)庫(kù)搜索服務(wù),以方便大家的日常開發(fā)工作。


? 溫習(xí)回顧上一篇(點(diǎn)擊跳轉(zhuǎn))
《【Maven教程】(四)坐標(biāo)與依賴:坐標(biāo)概念,依賴配置、范圍、傳遞性和最佳實(shí)踐 ~》

? 繼續(xù)閱讀下一篇(點(diǎn)擊跳轉(zhuǎn))
《【Maven教程】(六)生命周期和插件:三種生命周期、命令行與生命周期對(duì)應(yīng)的關(guān)系,插件目標(biāo)和綁定方式,插件配置的多種方法,獲取插件信息的技巧及插件解析機(jī)制~ ~》
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-699414.html

【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~,Maven教程,maven,java,學(xué)習(xí),開發(fā)語(yǔ)言,jvm,經(jīng)驗(yàn)分享

到了這里,關(guān)于【Maven教程】(五)倉(cāng)庫(kù):解析Maven倉(cāng)庫(kù)—布局、分類和配置,遠(yuǎn)程倉(cāng)庫(kù)的認(rèn)證與部署,快照版本,依賴解析機(jī)制,鏡像和搜索服務(wù) ~的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • maven本地倉(cāng)庫(kù)有依賴包,還會(huì)遠(yuǎn)程下載的問題

    maven本地倉(cāng)庫(kù)有依賴包,還會(huì)遠(yuǎn)程下載的問題

    遇見這樣的問題,明明本地有需要的依賴包,但是maven還是會(huì)從遠(yuǎn)程倉(cāng)庫(kù)拉取,如果遠(yuǎn)程倉(cāng)庫(kù)有需要的包還好,如果沒有,或者無(wú)網(wǎng)絡(luò)環(huán)境下沒法訪問遠(yuǎn)程倉(cāng)庫(kù),那就直接報(bào)錯(cuò),走不下去了。 原因:在本地倉(cāng)庫(kù)的每個(gè)依賴包都存在這樣的文件:_remote.repositories ?_remote.reposito

    2024年02月11日
    瀏覽(17)
  • 工具系列(七) 本文(4萬(wàn)字) | Git入門教程 | 初始本地倉(cāng)庫(kù)-推送合并到遠(yuǎn)程倉(cāng)庫(kù) | 解讀VScode與PyCharm配置與使用git | CodeGeeX與Tabnine使用 |

    點(diǎn)擊進(jìn)入專欄: 《人工智能專欄》 Python與Python | 機(jī)器學(xué)習(xí) | 深度學(xué)習(xí) | 目標(biāo)檢測(cè) | YOLOv5及其改進(jìn) | YOLOv8及其改進(jìn) | 關(guān)鍵知識(shí)點(diǎn) | 各種工具教程

    2024年02月21日
    瀏覽(102)
  • 私有倉(cāng)庫(kù)工具Nexus Maven如何部署并實(shí)現(xiàn)遠(yuǎn)程訪問管理界面

    私有倉(cāng)庫(kù)工具Nexus Maven如何部署并實(shí)現(xiàn)遠(yuǎn)程訪問管理界面

    Nexus是一個(gè)倉(cāng)庫(kù)管理工具,用于管理和組織軟件構(gòu)建過程中的依賴項(xiàng)和構(gòu)件。它與Maven密切相關(guān),可以作為Maven倉(cāng)庫(kù)的服務(wù)器。Nexus提供了一個(gè)集中式的位置,用于存儲(chǔ)和共享構(gòu)件,使團(tuán)隊(duì)成員能夠方便地訪問和部署這些構(gòu)件。 Cpolar內(nèi)網(wǎng)穿透是一種安全的內(nèi)網(wǎng)穿透云服務(wù),可以

    2024年01月18日
    瀏覽(22)
  • 配置idea自帶的maven,配置maven的阿里云倉(cāng)庫(kù)

    配置idea自帶的maven,配置maven的阿里云倉(cāng)庫(kù)

    idea中是有著自帶maven的,這種自帶的maven對(duì)于新手是非常友好的,它屏蔽了挺多的細(xì)節(jié),方便新手的使用。但是idea自帶maven一般是只能idea自己使用的,而且這個(gè)maven數(shù)據(jù)都是放在c盤。所以建議大家以后還是自己另外安裝maven使用。 首先找到File -settings-Build,Execution,Deployment-Bui

    2024年02月11日
    瀏覽(93)
  • Maven多倉(cāng)庫(kù)配置

    Maven多倉(cāng)庫(kù)配置

    有兩種方式配置Maven多倉(cāng)庫(kù) setting.xml文件的profiles標(biāo)簽 pom.xml文件的repositories標(biāo)簽 在使用多倉(cāng)庫(kù)配置時(shí),不管使用哪種方式,必須先將setting.xml文件中的mirrors標(biāo)簽修改為如下內(nèi)容(如果有mirrors標(biāo)簽),關(guān)鍵是mirrorOf千萬(wàn)不要寫成*,否則多倉(cāng)庫(kù)配置不生效 兩種方式可以同時(shí)使用

    2024年02月12日
    瀏覽(18)
  • 配置Maven倉(cāng)庫(kù)

    配置Maven倉(cāng)庫(kù)

    一、下載安裝maven maven下載官網(wǎng):https://maven.apache.org/download.cgi 下載到本地后解壓 二、配置環(huán)境變量 我的電腦-屬性-高級(jí)系統(tǒng)設(shè)置-環(huán)境變量/系統(tǒng)變量 新建MAVEN_HOME 變量值為自己的maven包所在的位置 編輯path 添加 %MAVEN_HOME%bin 三、測(cè)試 Win + R 輸入cmd打開DOS窗口,輸入mvn -v 或者

    2024年02月14日
    瀏覽(26)
  • 配置maven使用本地倉(cāng)庫(kù)

    配置maven使用本地倉(cāng)庫(kù)

    由于工作時(shí)是在內(nèi)網(wǎng)環(huán)境,maven無(wú)法連接互聯(lián)網(wǎng),所以只能事先將jar下載到本地,然后通過配置pom文件,將jar引用至本地倉(cāng)庫(kù)即可。 1、首先,我們需要打開本地的倉(cāng)庫(kù),查看此文件 2、記住此文件的倉(cāng)庫(kù)鏡像:比如我的是 sf-group (私服) 3、轉(zhuǎn)到maven的settings.xml文件,將此文件的

    2024年02月16日
    瀏覽(16)
  • maven安裝、使用、配置本地倉(cāng)庫(kù)、idea配置maven、解決plugins報(bào)錯(cuò)

    maven安裝、使用、配置本地倉(cāng)庫(kù)、idea配置maven、解決plugins報(bào)錯(cuò)

    注意:安裝maven環(huán)境之前要先安裝jdk環(huán)境。為了避免后期出現(xiàn)不必要的錯(cuò)誤, 文件的路徑不要有中文 1、去 我的電腦 ---- 系統(tǒng)環(huán)境 中配置 2、在 系統(tǒng)變量 中找到 Path ,選擇編輯 3、驗(yàn)證maven是否安裝成功:win+R輸入cmd,調(diào)出doc(終端)窗口,輸入 mvn -version 即可。 假如出現(xiàn)上

    2024年02月04日
    瀏覽(21)
  • 配置Maven本地倉(cāng)庫(kù)(idea)

    配置Maven本地倉(cāng)庫(kù)(idea)

    目錄 一、下載Maven安裝包Downloading Apache Maven (注意:Maven的版本需要老于IDEA的版本,否則導(dǎo)入Maven工程時(shí)會(huì)報(bào)錯(cuò)!) ???????? 文章末尾提示如何查詢idea版本 二、在任意文件夾中解壓下載的文件(并創(chuàng)建目錄文件夾) 三、配置環(huán)境變量 四、配置本地倉(cāng)庫(kù)和鏡像 五、idea配置

    2024年02月03日
    瀏覽(18)
  • maven配置阿里云鏡像倉(cāng)庫(kù)

    maven配置阿里云鏡像倉(cāng)庫(kù)

    ? ?

    2024年02月03日
    瀏覽(102)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包