一、Maven有哪些優點和缺點
優點如下:
- 簡化了項目依賴管理:
- 易于上手,對于新手可能一個"mvn clean package"指令就可能滿足他的工作
- 便于與持續內建工具(jenkins)整合
- 便于項目更新,無論是項目本身更新還是項目使用的依賴更新。
- 有助于多子產品項目的開發,一個子產品開發好後,釋出到倉庫,依賴該子產品時可以直接從倉庫更新,而不用自己去編譯。
- maven有很多插件,便于功能擴充,比如生産站點,自動釋出版本等
缺點如下:
- maven是一個龐大的建構系統,學習難度大
- maven采用約定優于配置的政策(convention over configuration),雖然上手容易,但是一旦出了問題,難于調試。
- 當依賴很多時,m2eclipse 老是搞得Eclipse很卡。
- 中國的網絡環境差,很多repository無法通路,比如google code, jboss 倉庫無法通路等。
二、Maven坐标
一般maven使用[groupID,artifactId,version,packaging]來表示一個項目的某個版本,有時還會使用classifier來表示項目的附屬建構,常見的附屬建構有javadoc和sources包。
三、Maven常見的依賴範圍有哪些?
- compile:編譯依賴,預設的依賴方式,在編譯(編譯項目和編譯測試用例),運作測試用例,運作(項目實際運作)三個階段都有效,典型地有spring-core等jar。
- test:測試依賴,隻在編譯測試用例和運作測試用例有效,典型地有JUnit。
- provided:對于編譯和測試有效,不會打包進釋出包中,典型的例子為servlet-api,一般的web工程運作時都使用容器的servlet-api。
- runtime:隻在運作測試用例和實際運作時有效,典型地是jdbc驅動jar包。
- system: 不從maven倉庫擷取該jar,而是通過systemPath指定該jar的路徑。
- import: 用于一個dependencyManagement對另一個dependencyManagement的繼承。
四、Maven的生命周期
maven有三套生命周期,分别為:
1、clean 周期:主要用于清理上一次建構産生的檔案,可以了解為删除target目錄
2、預設周期,
主要階段包含:
- process-resources 預設處理src/test/resources/下的檔案,将其輸出到測試的classpath目錄中,
- compile 編譯src/main/java下的java檔案,産生對應的class,
- process-test-resources 預設處理src/test/resources/下的檔案,将其輸出到測試的classpath目錄中,
- test-compile 編譯src/test/java下的java檔案,産生對應的class,
- test 運作測試用例,
- package 打包構件,即生成對應的jar, war等,
- install将構件部署到本地倉庫,
- deploy 部署構件到遠端倉庫
3、site周期
主要階段包含
- site 産生項目的站點文檔
- site-deploy 将項目的站點文檔部署到伺服器
五、我們經常使用“Mvn Clean Package”指令進行項目打包,請問該指令執行了哪些動作來完成該任務?
在這個指令中我們調用了maven的clean周期的clean階段綁定的插件任務,以及default周期的package階段綁定的插件任務
預設執行的任務有(maven的術語叫goal, 也有人翻譯成目标,我這裡用任務啦):
- maven-clean-plugin:clean->
- maven-resources-plugin:resources->
- maven-compile-plugin:compile->
- mavne-resources-plugin:testResources->
- maven-compile-plugin:testCompile->
- maven-jar-plugin:jar
六、依賴的解析機制
- 解析釋出版本:如果本地有,直接使用本地的,沒有就向遠端倉庫請求。
- 解析快照版本:合并本地和遠端倉庫的中繼資料檔案-groupId/artifactId/version/maven-metadata.xml,這個檔案存的版本都是帶時間戳的,将最新的一個改名為不帶時間戳的格式供本次編譯使用。
- 解析版本為LATEST,RELEASE,過于複雜,且解析的結果不穩定, 不推薦在項目中使用,感興趣的同學自己去研究,簡而言之就是合并groupId/artifactId/maven-metadata.xml找到對應的最新版本和包含快照的最新版本。
七、插件的解析機制
當我們輸入"mvn dependency:tree"這樣的指令,解析的步驟為:
解析groupID:
maven使用預設的groupID:"org.apache.maven.plugins"或者"org.codehaus.mojo"
解析artifactId(maven的官方叫做插件字首解析政策)
合并該groupId在所有倉庫中的中繼資料庫檔案(maven-metadata-repository.xml),比如maven官方插件的中繼資料檔案所在的目錄為org\apache\maven\plugins,該檔案下有如下的條目
1 2 3 4 5 | <plugin> <name>Maven Dependency Plugin</name> <prefix>dependency</prefix> <artifactId>maven-dependency-plugin</artifactId> </plugin> |
通過比較這樣的條目,我們就将該指令的artifactId解析為maven-dependency-plugin
解析version
如果你在項目的pom中聲明了該插件的版本,那麼直接使用該版本的插件,否則合并所有倉庫中groupId/artifactId/maven-metadata-repository.xml,找到最新的釋出版本。
對于非官方的插件,有如下兩個方法可以選擇:
1)使用groupId:artifactId:version:goal 來運作,好長~~~~~~~~~~
2)在Settings.xml中添加pluginGroup項,這樣maven不能在官方的插件庫中解析到某個插件,那麼就可以去你配置的group下查找啦。
八、多子產品如何聚合
配置一個打包類型為pom的聚合子產品,然後在該pom中使用<module>元素聲明要聚合的子產品
九、對于一個多子產品項目,如果管理項目依賴的版本
通過在父子產品中聲明dependencyManagement和pluginManagement, 然後讓子子產品通過<parent>元素指定父子產品,這樣子子產品在定義依賴是就可以隻定義groupId和artifactId,自動使用父子產品的version,這樣統一整個項目的依賴的版本。
十、一個項目的依賴來源于不同的組織,可能這些依賴還會依賴别的Jar包,如何保證這些傳遞依賴不會引起版本沖突。
使用<dependency>的<exclusion>元素将會引起沖突的元素排除。
十一、常見的Maven私服的倉庫類型。
(宿主倉庫)hosted repository, (代理倉庫)proxy repository, (倉庫組)group repository
十二、如何查詢一個插件有哪些目标(Goal)
mvn help:describe -Dplugin=groupId:artifactId
from: http://www.javacoder.cn/?p=211