pom配置 倉庫資訊
遠端倉庫的配置
在平時的開發中,我們往往不會使用預設的中央倉庫,預設的中央倉庫訪問的速度比較慢,訪問的人或許很多,有時候也無法滿足我們專案的需求,可能專案需要的某些構件中央倉庫中是沒有的,而在其他遠端倉庫中有,如JBossMaven倉庫。這時,可以在pom.xml中配置該倉庫,程式碼如下:
<!--配置遠端倉庫--> <repositories> <repository> <id>jboss</id> <name>JBossRepository</name> <url>http://repository.jboss.com/maven2/</url> <releases> <enabled>true</enabled> <updatePolicy>daily</updatePolicy> </releases> <snapshots> <enabled>false</enabled> <checksumPolicy>warn</checksumPolicy> </snapshots> <layout>default</layout> </repository> </repositories>
repository:在repositories元素下,可以使用repository子元素宣告一個或者多個遠端倉庫。
id:倉庫宣告的唯一id,尤其需要注意的是,Maven自帶的中央倉庫使用的id為central,如果其他倉庫宣告也使用該id,就會覆蓋中央倉庫的配置。
name:倉庫的名稱,讓我們直觀方便的知道倉庫是哪個,暫時沒發現其他太大的含義。
url:指向了倉庫的地址,一般來說,該地址都基於http協議,Maven使用者都可以在瀏覽器中開啟倉庫地址瀏覽構件。
releases和snapshots:用來控制Maven對於釋出版構件和快照版構件的下載許可權。需要注意的是enabled子元素,該例中releases的enabled值為true,表示開啟JBoss倉庫的釋出版本下載支援,而snapshots的enabled值為false,表示關閉JBoss倉庫的快照版本的下載支援。根據該配置,Maven只會從JBoss倉庫下載釋出版的構件,而不會下載快照版的構件。
layout:元素值default表示倉庫的佈局是Maven2及Maven3的預設佈局,而不是Maven1的佈局。基本不會用到Maven1的佈局。
其他:對於releases和snapshots來說,除了enabled,它們還包含另外兩個子元素updatePolicy和checksumPolicy。
1:元素updatePolicy用來配置Maven從遠處倉庫檢查更新的頻率,預設值是daily,表示Maven每天檢查一次。其他可用的值包括:never-從不檢查更新;always-每次構建都檢查更新;interval:X-每隔X分鐘檢查一次更新(X為任意整數)。
2:元素checksumPolicy用來配置Maven檢查校驗和檔案的策略。當構建被部署到Maven倉庫中時,會同時部署對應的檢驗和檔案。在下載構件的時候,Maven會驗證校驗和檔案,如果校驗和驗證失敗,當checksumPolicy的值為預設的warn時,Maven會在執行構建時輸出警告資訊,其他可用的值包括:fail-Maven遇到校驗和錯誤就讓構建失敗;ignore-使Maven完全忽略校驗和錯誤。
遠端倉庫的認證
大部分的遠端倉庫不需要認證,但是如果是自己內部使用,為了安全起見,還是要配置認證資訊的。
配置認證資訊和配置遠端倉庫不同,遠端倉庫可以直接在pom.xml中配置,但是認證資訊必須配置在settings.xml檔案中。這是因為pom往往是被提交到程式碼倉庫中供所有成員訪問的,而settings.xml一般只存在於本機。因此,在settings.xml中配置認證資訊更為安全。
<settings>
...
<!--配置遠端倉庫認證資訊-->
<servers>
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
...
</settings>
這裡除了配置賬號密碼之外,值關鍵的就是id了,這個id要跟你在pom.xml裡面配置的遠端倉庫repository的id一致,正是這個id將認證資訊與倉庫配置聯絡在了一起。
部署構件至遠端倉庫
我們自己搭建遠端倉庫的目的就是為了可以方便部署我們自己專案的構件以及一些無法從外部倉庫直接獲取的構件。這樣才能在開發時,供其他對團隊成員使用。
Maven除了能對專案進行編譯、測試、打包之外,還能將專案生成的構件部署到遠端倉庫中。首先,需要編輯專案的pom.xml檔案。配置distributionManagement元素,程式碼如下:
<distributionManagement>
<repository>
<id>releases</id>
<name>public</name>
<url>http://59.50.95.66:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Snapshots</name>
<url>http://59.50.95.66:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
看程式碼,從命名上就看的出來區別,repository表示表示釋出版本(穩定版本)構件的倉庫,snapshotRepository表示快照版本(開發測試版本)的倉庫。這兩個元素都需要配置id、name和url,id為遠端倉庫的唯一標識,name是為了方便人閱讀,關鍵的url表示該倉庫的地址。
配置好了就執行命令mvncleandeploy,Maven就會將專案構建輸出的構件部署到配置對應的遠端倉庫,如果專案當前的版本是快照版本,則部署到快照版本的倉庫地址,否則就部署到釋出版本的倉庫地址。
當前專案是快照還是釋出版本是通過true這個來區分的。忘記的同學在看看上面的##遠端倉庫的配置。
映象
如果倉庫X可以提供倉庫Y儲存的所有內容,那麼就可以認為X是Y的一個映象。用過Maven的都知道,國外的中央倉庫用起來太慢了,所以選擇一個國內的映象就很有必要,我推薦國內的阿里雲映象。
阿里雲映象:配置很簡單,修改conf資料夾下的settings.xml檔案,新增如下映象配置:
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyunmaven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
上例子中,的值為central,表示該配置為中央庫的映象,任何對於中央倉庫的請求都會轉至該映象,使用者也可以用同樣的方法配置其他倉庫的映象
這裡介紹下<mirrorOf>
配置的各種選項
<mirrorOf>*<mirrorOf>
:匹配所有遠端倉庫。<mirrorOf>external:*<mirrorOf>
:匹配所有遠端倉庫,使用localhost的除外,使用file://協議的除外。也就是說,匹配所有不在本機上的遠端倉庫。<mirrorOf>repo1,repo2<mirrorOf>
:匹配倉庫repo1h和repo2,使用逗號分隔多個遠端倉庫。<mirrorOf>*,!repo1<mirrorOf>
:匹配所有遠端倉庫,repo1除外,使用感嘆號將倉庫從匹配中排除。
需要注意的是,由於映象倉庫完全遮蔽了被映象倉庫,當映象倉庫不穩定或者停止服務的時候,Maven仍將無法訪問被映象倉庫,因而將無法下載構件。
其它映象:
http://www.sonatype.org/nexus/ 私服nexus工具使用
http://mvnrepository.com/ (推薦)
http://repo1.maven.org/maven2
http://maven.aliyun.com/nexus/content/groups/public/ 阿里雲 (強力推薦)
http://repo2.maven.org/maven2/ 私服nexus工具使用
http://uk.maven.org/maven2/
http://repository.jboss.org/nexus/content/groups/public
http://maven.oschina.net/content/groups/public/
http://mirrors.ibiblio.org/maven2/
http://maven.antelink.com/content/repositories/central/
http://nexus.openkoala.org/nexus/content/groups/Koala-release/
http://maven.tmatesoft.com/content/groups/public/
典型的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 模型版本。maven2.0必須是這樣寫,現在是maven2唯一支援的版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 公司或者組織的唯一標誌,並且配置時生成的路徑也是由此生成, 如com.winner.trade,maven會將該專案打成的jar包放本地路徑:/com/winner/trade -->
<groupId>com.winner.trade</groupId>
<!-- 本專案的唯一ID,一個groupId下面可能多個專案,就是靠artifactId來區分的 -->
<artifactId>trade-core</artifactId>
<!-- 本專案目前所處的版本號 -->
<version>1.0.0-SNAPSHOT</version>
<!-- 打包的機制,如pom,jar, maven-plugin, ejb, war, ear, rar, par,預設為jar -->
<packaging>jar</packaging>
<!-- 幫助定義構件輸出的一些附屬構件,附屬構件與主構件對應,有時候需要加上classifier才能唯一的確定該構件 不能直接定義專案的classifer,因為附屬構件不是專案直接預設生成的,而是由附加的外掛幫助生成的 -->
<classifier>...</classifier>
<!-- 定義本專案的依賴關係 -->
<dependencies>
<!-- 每個dependency都對應這一個jar包 -->
<dependency>
<!--一般情況下,maven是通過groupId、artifactId、version這三個元素值(俗稱座標)來檢索該構件, 然後引入你的工程。如果別人想引用你現在開發的這個專案(前提是已開發完畢併發布到了遠端倉庫),-->
<!--就需要在他的pom檔案中新建一個dependency節點,將本專案的groupId、artifactId、version寫入, maven就會把你上傳的jar包下載到他的本地 -->
<groupId>com.winner.trade</groupId>
<artifactId>trade-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- maven認為,程式對外部的依賴會隨著程式的所處階段和應用場景而變化,所以maven中的依賴關係有作用域(scope)的限制。 -->
<!--scope包含如下的取值:compile(編譯範圍)、provided(已提供範圍)、runtime(執行時範圍)、test(測試範圍)、system(系統範圍) -->
<scope>test</scope>
<!-- 設定指依賴是否可選,預設為false,即子專案預設都繼承:為true,則子專案必需顯示的引入,與dependencyManagement裡定義的依賴類似 -->
<optional>false</optional>
<!-- 遮蔽依賴關係。 比如專案中使用的libA依賴某個庫的1.0版,libB依賴某個庫的2.0版,現在想統一使用2.0版,就應該遮蔽掉對1.0版的依賴 -->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 為pom定義一些常量,在pom中的其它地方可以直接引用 使用方式 如下 :${file.encoding} -->
<properties>
<file.encoding>UTF-8</file.encoding>
<java.source.version>1.5</java.source.version>
<java.target.version>1.5</java.target.version>
</properties>
...
</project>
這裡有必要對一個不太常用的屬性classifier做一下解釋,因為有時候引用某個jar包,classifier不寫的話會報錯。
classifier元素用來幫助定義構件輸出的一些附屬構件。附屬構件與主構件對應,比如主構件是 kimi-app-2.0.0.jar,該專案可能還會通過使用一些外掛生成 如kimi-app-2.0.0-javadoc.jar (Java文件)、 kimi-app-2.0.0-sources.jar(Java原始碼) 這樣兩個附屬構件。這時候,javadoc、sources就是這兩個附屬構件的classifier,這樣附屬構件也就擁有了自己唯一的座標。
classifier的用途在於:
- maven download javadoc / sources jar包的時候,需要藉助classifier指明要下載那個附屬構件
- 引入依賴的時候,有時候僅憑groupId、artifactId、version無法唯一的確定某個構件,需要藉助classifier來進一步明確目標。比如JSON-lib,有時候會同一個版本會提供多個jar包,在JDK1.5環境下是一套,在JDK1.3環境下是一套:
引用它的時候就要註明JDK版本,否則maven不知道你到底需要哪一套jar包:
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
基本的設定
POM包含了一個project所需要的所有資訊,當然也就包含了構建過程中所需要的外掛的配置資訊,事實上,這裡申明瞭"who","what",和"where",然而構建生命週期(build lifecycle)s中說的是"when"和"how"。這並不是說POM並能影響生命週期的過程-事實上它可以。
例如,配置一個可以嵌入ant任務到POM的mavem-antrun-plugin。它基本上就是一個宣告。就像build.xml告訴ant當執行時它該做什麼一樣,一個POM申明瞭它自己的配置。如果外力迫使生命週期跳過了ant外掛的執行,這並不影響那些已經執行過的外掛產生的效果。這一點和build.xml不一樣。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
上面的POM定義的是Maven2或3都承認的最小部分。groupId: artifactId:version
是必須的欄位(儘管在繼承中groupId和version不需要明確指出)。這三個欄位就像地址和郵戳,它標記了倉庫中的特定位置,就像Maven projects的座標系統一樣。