前言
相信只要做過 Java 開發的童鞋們,對 Ant 想必都不陌生,我們往往使用 Ant 來構建項目,尤其是涉及到特別繁雜的工作量,一個 build.xml 能夠完成編譯、測試、打包、部署等很多任務,這在很大的程度上解放了程序員們的雙手。但同時也存在一些其他的問題,比如:jar 文件管理混亂,每次都需要自己去下載;build.xml 因項目結構的不同導致差異性較大。
概況
自從項目中引入 Maven 以后,以前 Ant 能解決的,Maven 提供了更加簡潔的解決方案,而以前 Ant 解決不了的,Maven 也能很好的解決。這就直接導致了項目管理工具的更新換代。當然,這已不是什么新鮮事了。只不過,一直到現在才有時間來分享項目中使用 Maven 的感受,這一點上,真的很抱歉,后續會及時的更新。
Maven 的入門教程網上已經有很多了,這里就不再贅述這些基本知識了。還沒有接觸過 Maven 的童鞋,請移步 Google 或 Baidu。之后再回來看這篇文章。在這篇文章里,我主要結合項目中 Maven 的使用,以及需要注意的事項來與大家討論。
原理
說到 Maven 的原理,其實很簡單,就是采用遠程倉庫和本地倉庫以及一個類似 build.xml 的 pom.xml,將 pom.xml 中定義的 jar 文件從遠程倉庫下載到本地倉庫,各個應用使用同一個本地倉庫的 jar,同一個版本的 jar 只需下載一次,而且避免每個應用都去拷貝 jar。
同時它采用了現在流行的插件體系架構,只保留最小的核心,其余功能都通過插件的形式提供,所以 Maven 下載很小(1.1M),在執行 Maven 任務時,才會自動下載需要的插件。而且,Maven 還是跨平臺的,并且提供了支持很多 Java IDE 的擴展插件。在開發中,我們大部分的時間,用到的是 Maven 的插件。對于公司內部來說,還是需要建立自己的私服的,不過,這里私服不是重點,就不再討論了。
結構
項目中我們都會根據自己的習慣創建目錄結構,雖然有規范,但難免會有疏漏,長此下去,項目的結構會越來越亂的。Maven 解決了這個問題,對于不同的項目,它提供了多種選擇,并將其作為目錄模板,如下圖所示。
使用目錄模板,可以使pom.xml更簡潔。因為Maven2已經根據缺省目錄,預定義了相關的動作,而無需人工的干預。以resources目錄為例:?
src/main/resources,負責管理項目主體的資源。在使用Maven2執行compile之后,這個目錄中的所有文件及子目錄,會復制到target/classes目錄中,為以后的打包提供了方便。?
src/test/resources,負責管理項目測試的資源。在使用Maven2執行test-compile之后,這個目錄中的所有文件及子目錄,會復制到target/test-classes目錄中,為后續的測試做好了準備。?
這些動作在 Maven1 中,是需要在 maven.xml 中使用或來完成的。如今,完全不需要在pom.xml中指定就能夠自動完成。在src和test都使用resources,方便構建和測試,這種方式本就已是前人的經驗。通過使用Maven2,使這個經驗在開發團隊中得到普及。
生命周期
在 Maven2 中有了明確的生命周期概念,而且都提供與之對應的命令,使得項目構建更加清晰明了。主要的生命周期階段:
validate,驗證工程是否正確,所有需要的資源是否可用。
verify,運行任何檢查,驗證包是否有效且達到質量標準。
integration-test,在集成測試可以運行的環境中處理和發布包。
generate-sources,產生應用需要的任何額外的源代碼,如xdoclet。
compile,編譯項目的源代碼。
test-compile,編譯項目測試代碼。
test,使用已編譯的測試代碼,測試已編譯的源代碼。
package,已發布的格式,如jar,將已編譯的源代碼打包。
install,把包安裝在本地的repository中,可以被其他工程作為依賴來使用。
deploy,在整合或者發布環境下執行,將最終版本的包拷貝到遠程的repository,使得其他的開發者或者工程可以共享。
如果要執行項目編譯,那么直接輸入:mvn compile即可,對于其他的階段可以類推。階段之間是存在依賴關系(dependency)的,如test依賴test-compile。在執行mvn test時,會先運行mvn test-compile,然后才是mvn test。當然,開發中,我們一般都不會直接操作 Maven 的。而是在 Eclipse 中使用 Maven 插件,其中用的最多的命令就是 clean 、compile 、install 、deploy 等。
依賴
說完生命周期,還有一個必須要說的就是依賴管理了。Maven 中是通過在 pom.xml 中添加依賴從而來引入 jar 包的。其原理是:每一個 jar 都會有獨立的坐標,Maven 就是通過坐標來定位到具體的 jar 的。
就好像平面坐標系一樣,通過 x 軸 和 y 軸定位一個坐標點。Maven 定義了這樣一組規則:世界上任何一個構件都可以使用 Maven 坐標唯一標識,Maven 坐標的元素包括 groupId 、artifactId 、version 、packaging 、classifier 。只要我們提供正確的坐標元素,Maven 就能夠找到它。
建議
有的人可能會有疑問,以前沒有 Maven 的時候,我們可以去各自的官網下載 jar,但現在只能通過 pom 引用 jar。那么如何知道需要添加哪些依賴呢?還有需要什么版本呢?這也是為什么有一部分習慣了自己下載 jar,而到了 Maven 這不知道該怎么用了。
當然,Maven 還不是智能的,你不可能直接命令 Maven 直接給你找項目所需要的各種組件,或許以后這樣的智能化的軟件管理工具會出現,至少現在還沒有。因此,還得需要你自己去添加 pom 依賴。至于該如何找,這里我告訴大家一個方法,雖然方法有點笨,但或許對你快速定位到具體組件有所幫助。
舉個例子,假如現在需要添加 Hibernate 的依賴,但具體哪個版本呢,可以先不用管,直接去 Baidu 或者 Google,以“ maven spring ?repository ”為關鍵字搜索,往往第一個鏈接中,就是你需要的方案。
進入第一鏈接之后,你會看到這樣一個頁面,搜索的結果都是關于 Spring 的,根據你的需要,選擇一個鏈接進入,列表中有各個版本的組件,點擊你需要的版本,然后就會看到 Maven 坐標。把它復制到你的 pom 文件中就噢啦。
當然,這只是一種方法,只針對剛接觸 Maven 的童鞋們。隨著項目經驗的增多,以后你就會越來越發現,Maven 解放的不僅僅是你的雙手,還有你最寶貴的時間。
感受
在一個項目中選擇使用一款管理工具是有風險的,那么該如何把這種風險減到最低,或者讓它轉變為對項目開發有利的一方面呢?這就需要架構師或者項目組長,在項目開始之前進行嚴格的技術考察、技術(工具)選型、學習成本的分析等。
選擇一種技術或者一款工具,不能僅僅因為它的流行程度,還要考慮到本公司開發人員的技術程度,技術(工具)的跨平臺性考慮,擴展性與集成性的考慮,以及技術(工具)穩定性的考慮等。當然,對于一種新技術(對開發人員來說是新技術),還需要考慮學習成本,這些都制約日后的開發效率、開發進度,以及出問題后能不能解決等。
所謂的技術選型,并不是選出多么新的技術,也并不是選出成本最低的技術,而是能夠利用本公司的優勢,找出最適合本公司的技術和工具,在有限的范圍內、有限的時間內把本公司的能力發揮到最大。
就比如,如果在項目管理工具上,公司里一直都在用 Ant,而且用的也特別的熟練,況且項目的時間特別緊急,公司的開發人員對 Maven 都沒有接觸過,那么就不用再考慮 Maven 了,因為時間在那擺著呢,而且還有開發人員的學習成本,這種情況下再選擇 Maven,這不是 zuo si 嗎?當然,這種例子不勝枚舉,這里就不再多說了。
結束語
本來應該在最后說的話,都放在了感受里邊,對于項目管理,還有很多欠缺的,希望在日后的工作中繼續積累經驗吧。當然,也希望大家能夠多交流,共同進步。
傳一后期精彩活動預告