需求背景
maven的一大功能時管理項目依賴,為了自動化解析任何一個java構件,Maven就必須將它們唯一標識,這就是通過maven坐標實現。
實現原理
maven定義了這樣一組規則:世界上任何一個構件都可以使用maven坐標唯一標識,坐標元素包括:groupId、artifactId、version、packaging、classifier。只要提供正確的坐標就能從倉庫中找到相應的構件供我們使用。maven從哪里下載構件呢?答:maven內置了一個中央倉庫的地址,該中央倉庫包含了世界上大部分流行的開源構件。(當然有一些構件在倉庫中找不到,需要自己下載)
坐標詳解
任何構件都必須明確定義自己的坐標,而一組maven坐標是通過一些元素定義的,他們是:groupId、artifactId、version、packaging、classifier。
先看一組坐標定義如下:
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>
這是nexus-indexer項目的坐標,nexus-indexer是一個對maven倉庫編纂索引并提供搜索功能的類庫,它是Nexus項目的一個子模塊。
goupId: 定義了當前maven項目隸屬的實際項目,maven項目和實際項目不一定對應,比如SpringFramework這一實際項目,其對應的maven項目會有很多,如spring-core、spring-context等。groupId不應該對應到項目所屬公司,因為公司下面會有好多項目。
artifactId:該元素定義實際項目中的一個maven項目(模塊),推薦使用實際項目名稱作為artifactId前綴。如上例nexus-indexer使用nexus作為前綴,這樣做的好處是方便需找實際構件,因為maven生成構件名稱默認是以artifactId作為開頭。
version:定義maven項目當前所處版本。
packaging:定義maven項目的打包方式,首先打包方式通常與所生成構件的文件擴展名對應,如packaging為jar則構件擴展名為jar。packaging為war最終生成以.war結尾文件,但不是絕對。其次,打包方式會影響到構建項目的生命周期,比如jar打包和war打包會使用不同的命令。默認使用jar。
classifier:該元素用來幫助定義構件輸出的一些附屬構件。附屬構件與主構件對應,如上例的主構件是nexus-indexer-2.0.0.jar,該項目可能還會通過使用一些插件生成如nexus-indexer-javadoc.jar、nexus-indexer-source.jar這樣一些附屬構件,其包含了java文檔和源代碼。這時候,javadoc和sources就是這兩個附屬構件的classifier。這樣,附屬構件也就擁有了自己唯一的坐標。還有一個關于classifier的典型例子是TestNG,TestNG的主構件是基于java1.4平臺的,而它有提供了一個classifier為jdk1.5的附屬構件。注意,不能直接定義項目的classifier,因為附屬構件不是項目直接默認生成的,而是由附加的插件幫助生成的。主構件是項目在package階段是默認生成,而附屬構件需要插件來完成。
上述5元素groupId、artifactId、version是必須的,packaging可選,默認jar,classifier不能直接定義。同時,項目構件的文件名是與坐標對應的,一般的規則為artificatId-version[-classifier].packaging。packing并非一定與構件擴展名對應,比如packing為maven-plugin的構件擴展名為jar。