讀古今文學網 > Maven實戰 > 5.2 坐標詳解 >

5.2 坐標詳解

Maven坐標為各種構件引入了秩序,任何一個構件都必須明確定義自己的坐標,而一組Maven坐標是通過一些元素定義的,它們是groupId、artifactId、version、packaging、classifier。先看一組坐標定義,如下:

這是nexus-indexer的坐標定義,nexus-indexer是一個對Maven倉庫編纂索引並提供搜索功能的類庫,它是Nexus項目的一個子模塊。後面會詳細介紹Nexus。上述代碼片段中,其坐標分別為groupId:org.sonatype.nexus、artifactId:nexus-indexer、version:2.0.0、packaging:jar,沒有classifier。下面詳細解釋一下各個坐標元素:

·groupId:定義當前Maven項目隸屬的實際項目。首先,Maven項目和實際項目不一定是一對一的關係。比如SpringFramework這一實際項目,其對應的Maven項目會有很多,如spring-core、spring-context等。這是由於Maven中模塊的概念,因此,一個實際項目往往會被劃分成很多模塊。其次,groupId不應該對應項目隸屬的組織或公司。原因很簡單,一個組織下會有很多實際項目,如果groupId只定義到組織級別,而後面我們會看到,artifactId只能定義Maven項目(模塊),那麼實際項目這個層將難以定義。最後,groupId的表示方式與Java包名的表示方式類似,通常與域名反向一一對應。上例中,groupId為org.sonatype.nexus,org.sonatype表示Sonatype公司建立的一個非盈利性組織,nexus表示Nexus這一實際項目,該groupId與域名nexus.sonatype.org對應。

·artifactId:該元素定義實際項目中的一個Maven項目(模塊),推薦的做法是使用實際項目名稱作為artifactId的前綴。比如上例中的artifactId是nexus-indexer,使用了實際項目名nexus作為前綴,這樣做的好處是方便尋找實際構件。在默認情況下,Maven生成的構件,其文件名會以artifactId作為開頭,如nexus-indexer-2.0.0.jar,使用實際項目名稱作為前綴之後,就能方便從一個lib文件夾中找到某個項目的一組構件。考慮有5個項目,每個項目都有一個core模塊,如果沒有前綴,我們會看到很多core-1.2.jar這樣的文件,加上實際項目名前綴之後,便能很容易區分foo-core-1.2.jar、bar-core-1.2.jar……

·version:該元素定義Maven項目當前所處的版本,如上例中nexus-indexer的版本是2.0.0。需要注意的是,Maven定義了一套完成的版本規範,以及快照(SNAPSHOT)的概念。第13章會詳細討論版本管理內容。

·packaging:該元素定義Maven項目的打包方式。首先,打包方式通常與所生成構件的文件擴展名對應,如上例中packaging為jar,最終的文件名為nexus-indexer-2.0.0.jar,而使用war打包方式的Maven項目,最終生成的構件會有一個.war文件,不過這不是絕對的。其次,打包方式會影響到構建的生命週期,比如jar打包和war打包會使用不同的命令。最後,當不定義packaging的時候,Maven會使用默認值jar。

·classifier:該元素用來幫助定義構建輸出的一些附屬構件。附屬構件與主構件對應,如上例中的主構件是nexus-indexer-2.0.0.jar,該項目可能還會通過使用一些插件生成如nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar這樣一些附屬構件,其包含了Java文檔和源代碼。這時候,javadoc和sources就是這兩個附屬構件的classifier。這樣,附屬構件也就擁有了自己唯一的坐標。還有一個關於classifier的典型例子是TestNG,TestNG的主構件是基於Java 1.4平台的,而它又提供了一個classifier為jdk5的附屬構件。注意,不能直接定義項目的classifier,因為附屬構件不是項目直接默認生成的,而是由附加的插件幫助生成。

上述5個元素中,groupId、artifactId、version是必須定義的,packaging是可選的(默認為jar),而classifier是不能直接定義的。

同時,項目構件的文件名是與坐標相對應的,一般的規則為artifactId-version〔-classifier〕.packaging,〔-classifier〕表示可選。比如上例nexus-indexer的主構件為nexus-indexer-2.0.0.jar,附屬構件有nexus-indexer-2.0.0-javadoc.jar。這裡還要強調的一點是,packaging並非一定與構件擴展名對應,比如packaging為maven-plugin的構件擴展名為jar。

此外,Maven倉庫的佈局也是基於Maven坐標,這一點會在介紹Maven倉庫的時候詳細解釋。

理解清楚城市中地址的定義方式後,郵遞員就能夠開始工作了;同樣地,理解清楚Maven坐標之後,我們就能開始討論Maven的依賴管理了。