maven 倉庫
在以前使用Ant的時候,我們會建立一個lib目錄在存放我們的jar包,比如項目所依賴的第三方包,每建立一個項目都要建立一個lib,不停的做copy工作,不僅是對于磁盤的浪費,而且也造成了版本管理上的麻煩。而且我們還需要通過提交到svn上來對lib進行管理,但是svn對于這種二進制文件的管理并不出色。
Maven倉庫的初中就是為了解決這個問題,是所有常用的第三方包的集中營。這樣所有的Maven項目就可以從這個倉庫中獲取所需要的資源,Maven倉庫中對jar通過Group Id, Atifact Id, version 來管理,所以Maven項目可以很方便的進行依賴管理。你不需要自己來管理這個龐大的資源倉庫,當然你可以創建一個公司層面的倉庫管理器,這個我在這個章節的后面會介紹。
Maven 倉庫的兩個概念:本地倉庫和遠程倉庫
本地倉庫是遠程倉庫的一個緩沖和子集,當你構建Maven項目的時候,首先會從本地倉庫查找資源,如果沒有,那么Maven會從遠程倉庫下載到你本地倉庫。這樣在你下次使用的時候就不需要從遠程下載了。如果你所需要的jar包版本在本地倉庫沒有,而且也不存在于遠程倉庫,Maven在構建的時候會報錯,這種情況可能發生在有些jar包的新版本沒有在Maven倉庫中及時更新。
Maven缺省的本地倉庫地址為${user.home}/.m2/repository
。也就是說,一個用戶會對應的擁有一個本地倉庫。當然你可以通過修改${user.home}/.m2/settings.xml 配置這個地址:
…
<localRepository> D:/java/repository</localRepository>
…
</settings>
如果你想讓所有的用戶使用統一的配置那么你可以修改Maven主目錄下的setting.xml:
${M2_HOME}/conf/setting.xml
還可以通過在運行時指定目錄,但是并不推薦這么做:
mvn clean install -Dmaven.repo.local=/home/juven/myrepo/
當我們創建一個簡單的Maven項目后(只需要在pom.xml配置好依賴),運行mvn clean
install就可以把項目構建好,不需要我們手工下載任何jar,這全靠中央倉庫的存在,它會自動從倉庫下載。這個倉庫的定義是在${M2_HOME}/lib/maven-2.0.10-uber.jar
里面。你可以在里面找到/org/apache/maven/project/pom-4.0.0.xml
這個文件,在這個文件里面定義了中央倉庫的地址:
<repository>
<id> central</id>
<name> Maven Repository Switchboard</name>
<layout> default</layout>
<url> http://repo1.maven.org/maven2</url>
<snapshots>
<enabled> false</enabled>
</snapshots>
</repository>
</repositories>
在 POM 中配置遠程倉庫
下面我介紹下如何在pom.xml里面配置遠程倉庫,我們需要在什么時候配置遠程倉庫呢?當你連接中央倉庫的速度比較慢時,或者你為你的公司搭建了自己的倉庫,比如Nexus倉庫管理(后面我會介紹),又或者你蘇需要的jar存在另外一個公共倉庫,比如我們配置一個國內的鏡像地址:
…
<repositories>
<repository>
<id> maven-net-cn</id>
<name> Maven China Mirror</name>
<url> http://maven.net.cn/content/groups/public/</url>
<releases>
<enabled> true</enabled>
</releases>
<snapshots>
<enabled> false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id> maven-net-cn</id>
<name> Maven China Mirror</name>
<url> http://maven.net.cn/content/groups/public/</url>
<releases>
<enabled> true</enabled>
</releases>
<snapshots>
<enabled> false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
…
</project>
這里我們可以看到,允許配置多個repository和 plugin repository,<releases><enabled>true</enabled></releases>告訴Maven可以從這個倉庫下載releases版本的構件,而<snapshots><enabled>false</enabled></snapshots>告訴Maven不要從這個倉庫下載snapshot版本的構件,之所以不讓你從這個倉庫下載snapshot版本,是因為這些版本是不穩定的,但是snapshot版本在我們內部項目開發的時候可是作用巨大,后面的問文章我會討論這個問題。至于<pluginRepositories>,這是配置Maven從什么地方下載插件構件,Maven的所有行為都是通過插件來完成的,其內部配置與<repository>類似,這里就不多說了。
盡管pom.xml中可以方便的哦配置中央倉庫,但是我并不推薦大家這么做,尤其是在大的公司中,因為一個公司會有很多的項目,如果每個項目都這樣配置,那么又開始做重復的copy工作了,如何解決呢,我們往下走
在 settings.xml 中配置遠程倉庫
Pom.xml的作用范圍是一個項目,一個公司不可能只做一個項目,那么為了避免重復配置,那么我們需要把一些公共信息配置在setting.xml中。但是setting.xml中并不支持<repositories>及<pluginRepositories>,為了解決這個問題我們使用profile:
…
<profiles>
<profile>
<id> myProfiel</id>
<!—在這里加入<repositories>及<pluginRepositories>–>
</profile>
</profiles>
<activeProfiles>
<activeProfile> myProfiel </activeProfile>
</activeProfiles>
…
</settings>
這里通過<activeProfile>元素來激活這個profile,這樣我們就可以全局的使用這個配置,不再需要為每個POM做重復的配置了。
Maven Profiles
Maven中的profile是一組可選的配置,可以用來設置或者覆蓋配置默認值。有了profile,你就可以為不同的環境定制構建。profile可以在pom.xml中配置,并給定一個id。然后你就可以在運行Maven的時候使用的命令行標記告訴Maven運行特定profile中的目標。以下pom.xml使用production profile覆蓋了默認的Compiler插件設置。
在實際的操作過程中,這里我們最好不要配置遠程倉庫,最好能夠通過nexus建立公司或者組織自己的倉庫,然后這把把地址指向自己的倉庫,后面我會介紹為什么要這么做,怎么做。
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>false</debug>
<optimize>true</optimize>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
要使用production profile來運行mvn install,你需要在命令行傳入-Pproduction參數。要驗證production profile覆蓋了默認的Compiler插件配置,可以像這樣以開啟調試輸出(-X) 的方式運行Maven。
如果你開始大量使用Maven profile,你會希望將profile從POM中分離,使用一個單獨的文件如profiles.xml。你可以混合使用定義在pom.xml中和外部profiles.xml文件中的profile。只需要將profiles元素放到${basedir}目錄下的profiles.xml文件中,然后照常運行Maven就可以。profiles.xml文件的大概內容如下
<profile>
<id>development</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>true</debug>
<optimize>false</optimize>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>false</debug>
<optimize>true</optimize>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
settings profile可以應用到所有你使用Maven構建的項目。你可以在兩個地方定義settings profile:定義在~/.m2/settings.xml中的用戶特定settings profile,或者定義在${M2_HOME}/conf/settings.xml中的全局settings profile。
配置鏡像
如果你想覆蓋中央倉庫的默認地址,那么這里我們就會使用的鏡像了,還在setting.xml里面配置:
…
<mirrors>
<mirror>
<id> maven-net-cn</id>
<name> Maven China Mirror</name>
<url> http://maven.net.cn/content/groups/public/</url>
<mirrorOf> central</mirrorOf>
</mirror>
</mirrors>
…
</settings>
這里解釋一下<mirrorOf>,表示只為central倉庫做鏡像,如果想為所有的倉庫做鏡像那么可以改為:<mirrorOf>*</mirrorOf>
如果你看到這里,請先不要著急,實際的項目經驗告訴我,只是這些還不夠,我們需要更快捷和高效的管理:
利用 Nexus 來構建企業級 Maven 倉庫
Nexus是Maven倉庫管理器,用來搭建一個本地倉庫服務器,這樣做的好處是便于管理,節省網絡資源,速度快,還有一個非常有用的功能就是可以通過項目的SNAPSHOT版本管理,來進行模塊間的高效依賴開發,下面會一一描述。
雖然你可以通過中央倉庫來獲取你所需要的jar包,但是現實往往是存在很多問題:
- 網速慢,你可能需要花很長的時間來下載你所需要的jar
- 如果你的公司很大,有幾百甚至幾千人再用Maven,那么這些人都去通過中央倉庫來獲取jar,那么這是一個很大的資源浪費
- 如果存在模塊之間的依賴開發,你的snapshot版本是不能夠被你的伙伴很方便的獲取。
- 在實際開發過程中,有些jar的版本可能在中央倉庫里面不存在,或者更新不及時,你是獲取不到這個jar的。
所有以上問題,通過Nexus這個日益流行的倉庫管理器可以輕松的解決。
-
- 這個倉庫是本地的,下載的速度是從遠程下載不可比的。
- 可以為你公司所有的Maven使用者服務,可以進行統一管理
- 后面我會介紹如何通過nexus來進行存在模塊依賴的項目的開發
- 你可以添加自己的第三方包。
我們從http://nexus.sonatype.org/downloads/ 來獲取最新版本,目前最新版本為1.3.4
Nexus提供了兩種安裝方式,一種是內嵌Jetty的bundle,只要你有JRE就能直接運行。第二種方式是WAR,你只須簡單的將其發布到web容器中即可使用。
1)Bundle 方式安裝解壓nexus-webapp-1.3. 4 -bundle.zip
至任意目錄,如D:/ tools ,轉到目錄D:/
tools/nexus-webapp-1.3. 4 /bin/jsw/windows-x86-32
,運行Nexus.bat ,如果你是在linux下安裝,那么就下載nexus-webapp-1.3.
4 -bundle. tar .gz, 解壓后轉到${NEXUS_HOME}/
nexus-webapp-1.3.3/bin/jsw/linux-x86-32,它還支持solaris,macos等操作系統。當你看到“Started
SelectChannelConnector@0.0.0.0:8081”之后,說明Nexus啟動成功了,然后打開瀏覽器,訪問http://127.0.0.1:8081/nexus,通過admin的帳號(admin)和密碼(admin123)登錄你會看到如下的頁面:
這里,可以管理倉庫,配置Nexus系統,管理任務,管理用戶,角色,權限,查看系統的RSS源,管理及查看系統日志,等等。
War 方式安裝
你可以同過war的方式以web應用的形式發布到你的應用服務器,比如tomcat。你所要做的就是下載war版本的文件,然后放到應用服務器的發布目錄即可,這里就不多講了。
到此我們已經安裝好Nexus,下面我來介紹下一些我們常用的功能和使用:
配置 中央倉庫
在左邊菜單欄里選擇Repositories,然后會出現右邊的畫面,右邊上半部分是列出來的repository,黑體字是類型為group的repository. 這里簡單介紹下幾種repository的類型:
- hosted,本地倉庫,通常我們會部署自己的構件到這一類型的倉庫。比如公司的第二方庫。
- proxy,代理倉庫,它們被用來代理遠程的公共倉庫,如maven中央倉庫。
- group,倉庫組,用來合并多個hosted/proxy倉庫,當你的項目希望在多個repository使用資源時就不需要多次引用了,只需要引用一個group即可。
Maven central是Maven的中央倉庫,點擊它并選擇configuration標簽欄,我們會看到下面的頁面
- Override local storage location: 在這個選項你可以配置你的Nexus本地倉庫的存放地址,用來覆蓋其默認的存放地址
- Remote storage location: 這里是遠程倉庫的地址,為了提高代理速度,你可以修改為國內的鏡像地址。默認值是http://repo1.maven.org/maven2/
添加代理倉庫
Maven
central是一個比較大的代理倉庫,如果你需要添加的一個代理倉庫,那么可以在點擊左邊慘淡欄里面的Repositories,然后右邊的頁面點擊add ->
add proxy repository, 之后出現以下頁面:
填寫相關信息保存即可。通常情況下,使用預設的代理倉庫已經能夠滿足大部分項目的需求了, 只有在特殊需求的情況下才會參加代理倉庫.
管理本地倉庫
我們前面講到類型為hosted的為本地倉庫,Nexus預定義了3個本地倉庫,分別是Releases, Snapshots, 3rd Party.
分別講一下這三個預置的倉庫都是做什么用的:
- Releases: 這里存放我們自己項目中發布的構建, 通常是Release版本的, 比如我們自己做了一個FTP Server的項目, 生成的構件為ftpserver.war, 我們就可以把這個構建發布到Nexus的Releases本地倉庫. 關于符合發布后面會有介紹.
- Snapshots: 這個倉庫非常的有用, 它的目的是讓我們可以發布那些非release版本, 非穩定版本, 比如我們在trunk下開發一個項目,在正式release之前你可能需要臨時發布一個版本給你的同伴使用, 因為你的同伴正在依賴你的模塊開發, 那么這個時候我們就可以發布Snapshot版本到這個倉庫, 你的同伴就可以通過簡單的命令來獲取和使用這個臨時版本.
- 3rd Party: 顧名思義, 第三方庫, 你可能會問不是有中央倉庫來管理第三方庫嘛, 沒錯, 這里的是指可以讓你添加自己的第三方庫, 比如有些構件在中央倉庫是不存在的. 比如你在中央倉庫找不到Oracle 的JDBC驅動, 這個時候我們就需要自己添加到3rd party倉庫.

Maven 倉庫組
倉庫組的概念是Maven沒有的,通過前面介紹可以了解到, 我們可以建立多個proxy代理倉庫,hosted本地倉庫,
如果沒有倉庫組的概念,我們如果需要引用這些倉庫的是時候需要一一加入到我們的setting.xml里面去, 有了倉庫的組的概念,
我們只需要做一次引用就可以了,把我們需要的倉庫加入到倉庫組即可.像這樣:
<repository>
<id>nexus</id>
<url>http://127.0.0.1:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Nexus中預設了2個倉庫組,public repositories和public snapshot repositories. 如圖:

倉庫組默認包含本地倉庫Releases, snapshots, 3rd party和代理倉庫Maven Central. 你可以在Configuration配置頁添加倉庫到這個倉庫組. 如果需要你還可以創建一個倉庫組,如圖:
點擊 Add->Repository Group
出現New Repository Group界面后,填入ID, name 等相關信息, 在右邊Available Repositories 欄里可以選擇你要添加的倉庫到你新建的倉庫組.

好多公司處于安全考慮,用代理上網,而nexus 經常需要往maven repository中心下載東西,所以需要給nexus設置代理。 開始沒找到地方,后來發現可以從nexus后臺管理器界面上直接設置,地方很隱蔽:
登陸后進入管理頁面,從左邊菜單欄選擇Server 打開右邊tab頁,發現還是找不到,別著急,仔細找會發現有行: default http proxy settings 前面有個checkbox 未勾選, 速度勾選之,馬上出現了您熟悉的 proxy host,proxy port , username , passowrd. okay 代理設置完成,現在nexus能通過互聯網從maven repository中心下載東西了!
通過 Nexus 搜索構件
在我們實際使用構件的過程中通常遇到一個問題,有時候我緊緊知道我所需要的構建的大致名字,并不知道全稱或group id, 這是件非常頭疼的事情. Nexus基于Nexus indexer的搜索功能幫我們解決了這個問題.
要是用搜索功能, 必須要有索引文件, Nexus默認是不建立索引文件的,因為像中央倉庫這樣的索引文件的建立需要耗費比較大的網絡資源,僅索引文件就要幾十兆.
要開啟中央倉庫的索引文件下載功能需要在Maven Central的配置頁面, 把Download Remote Indexes選擇true. 如圖:
這樣設置以后, Nexus會自動從遠程中央倉庫下載索引文件, 為了檢驗索引文件自動下載是否生效,可以卻換到Browse:
如果出現先以上文件夾,那說明索引文件已經建立.
下面我試一下搜索功能, 在左邊菜單欄里面有個Artifact Search, 在輸入框里面輸入你想要搜索的構件名字,比如: testing,
那么查詢結果如下:

比如我們這里選擇GAV模式, 而且我只知道artiface name : testng和版本號5.8, 其他的我不知道, 那么就在artifact 和 version處分別輸入testng 和 5.8 , 搜索結果如下:

你如果你不知道知道構件的名稱, 只知道classname, 那么你也可以通過class name 的方式搜索,這里就不再贅述
當你選擇一項搜索結果,在頁面的下方會出現這個構件的詳細信息, 并且會列出這個構件的Maven依賴配置,
你可以直接拷貝到你的pom文件中使用,這是個非常實用的功能:
在 Maven 中使用
Nexus
到此為止我們介紹了如何安裝和使用Nexus以及其基本配置, 下面我們介紹下如何讓Maven來使用Nexus本地倉庫用來替代使用遠程倉庫.
在Maven使用Nexus本地倉庫只需稍作配置, 在settings.xml中加入以下代碼:
<id>dev</id>
<repositories>
<repository>
<id>nexus</id>
<url>http://127.0.0.1:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url>http://127.0.0.1:8081/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
這里配置了repository和pluginRepository, Maven在使用第三方構件和插件時是分開來配置的,所以如果我們也希望插件的下載也通過我們的本地倉庫來下載,那么我們就需要配置pluginRepository.
紅色字體部分就是我們之前安裝的Nexus的地址, 這個地址可以是你們公司局域網內部的一臺倉庫服務器.
<releases> <enabled>true</enabled></releases>這個標簽的作用是設定是否允許下載
release版本的載構件, 同樣snapshots標簽可以設定是否允許下載snapshot版本的構件.
通常,我們不建議下載snapshot版本的構件,因為它是不穩定的版本, 除非你有特殊的需求
構件部署
有些時候我們需要部署構件到Nexus的3rd party, 比如我們在中央倉庫找不到我們需要的構件, 我們可以通過Nexus的UI來上傳構件:
點擊左邊菜單欄的 Repositories, 然后點擊右邊界面的3rd party, 選擇界面下方的Artifact Upload, 這個時候出現以下界面:

上傳構件需要兩個步驟,一個是定義文件的上傳,再就是構件的實體文件.
第一部分定義文件可以是POM文件, 這也是比較推薦的方式, 如果沒有pom文件,可以選擇以參數的形式輸入.第二部分是上傳構件的實體文件,這里簡單說一下Classifier和Extension, 這兩個都是選填相, Classifier用來區別同功能的構件用于不同的場景, 比如這個構件是分別針對JDK14和JDK15做了2個功能一樣的Jar, 這個時候你就需要指定這個構件的Classifier為JDK14還是JDK15. Extension是指擴展名,如果不提供,那么會自動取這個構件的Packaging Type作為擴展名, 比如 ear, jar, war 等等. (Packaging Type是在第一步中通過pom文件或者手工輸入得到的)剛才說了3rd party的部署, 關于releases 和 snapshots的UI部署也是一樣的操作過程.我們之前也講過, 這里的releases和snapshots是用來部署我們自己的項目構件的, 通過UI部署是可以,但是不是最高效的, 我們可以通過配置Maven來自動部署我們的項目構件,這也是我們建立自己的倉庫的一個非常重要的原因, 下面就讓我們看看如何配置:首先需要在POM文件中加入以下代碼:
…
<distributionManagement>
<repository>
<id> nexus-releases</id>
<name> Nexus Release Repository</name>
<url> http://127.0.0.1:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id> nexus-snapshots</id>
<name> Nexus Snapshot Repository</name>
<url> http://127.0.0.1:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
…
</project>
這里配置,讓Maven知道當我要發布release版本或者snapshot版本是需要發布到哪個地址.
然后我們需要在setting.xml里面配置一下Nexus的帳號和密碼:
…
<servers>
<server>
<id> nexus-releases</id>
<username> admin</username>
<password> admin123</password>
</server>
<server>
<id> nexus-snapshots</id>
<username> admin</username>
<password> admin123</password>
</server>
</servers>
…
</settings>
到此為止, 我們就可以通過命令mvn deploy或者通過IDE的可視化界面點擊deploy來發布我們項目到本地倉庫了. 通過這種方式我們可以很方便的進行模塊間的依賴開發, 在后面的文章中我會詳細介紹如何通過snapshot來讓我們的依賴開發變得簡單.
@import url(http://www.tkk7.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);