一、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