天天看點

Maven之——簡介Maven之——簡介

Maven之——簡介

        摘要:此篇筆記主要是對maven進行一個簡介、讓我們大緻了解maven是做什麼的、内容是對《Maven實戰》的摘要。強烈建議想學Maven的新手看這本書、當然也可以上網一些教學視訊、但是最重要的一條:動手!不管看着再簡單、也要自己動手試試!

一:何為Maven

        Maven這個詞可以翻譯為“知識的積累”,也可以翻譯為“專 家”或“内行”。本書将介紹Maven這一跨平台的項目管理工具。作為Apache組織中的一個頗為成功的開源項目,Maven主要服務于基于Java平台的項目建構、依賴管理和項目資訊管理。無論是小型的開源類庫項目,還是大型的企業級應用;無論是傳統的瀑布式開發,還是流行的靈活模式,Maven都能大顯身手。

        1.1  何為建構

                不管你是否意識到,建構(build)是每一位程式員每天都在做的工作。早上來 到公司,我們做的第一件事情就是從源碼庫簽出最新的源碼,然後進行單元測試,如果發現失敗的測試,會找相關的同僚一起調試,修複錯誤代碼。接着回到自己的工作上來,編寫自己的單元測試及産品代碼,我們會感激IDE随時報出的編譯錯誤提示。

                忙到午飯時間,代碼編寫得差不多了,測試也通過了,開心地享 用午餐,然後休息。下午先在昏昏沉沉中開了個例會,會議結束後喝杯咖啡繼續工作。剛才在會上經理要求看測試報告,于是找了相關工具內建進IDE,生成了像模像樣的測試覆寫率報告,接着發了一封電子郵件給經理,松了口氣。誰料QA小組又發過來了幾個bug,沒辦法,先本地重制再說,于是熟練地用IDE生成了一個WAR包,部署到Web容器下,啟動容器。看到熟悉的界面了,遵循bug報告,一步步重制了bug……快下班的時候,bug修好了,送出代碼,通知 QA小組,在愉快中結束了一天的工作。

                仔細總結一下,我們會發現,除了編寫源代碼,我們每天有相當一部分時間花在了編 譯、運作單元測試、生成文檔、打包和部署等煩瑣且不起眼的工作上,這就是建構。如果我們現在還手工這樣做,那成本也太高了,于是有人用軟體的方法讓這一系列工作完全自動化,使得軟體的建構可以像全自動流水線一樣,隻需要一條簡單的指令,所有煩瑣的步驟都能夠自動完成,很快就能得到最終結果。

        1.2  Maven是優秀的建構工具

                前面介紹了Maven的用途之一是服務于建構,它是一個異常強大的建構工具,能 夠幫我們自動化建構過程,從清理、編譯、測試到生成報告,再到打包和部署。我們不需要也不應該一遍又一遍地輸入指令,一次又一次地點選滑鼠,我們要做的是使用Maven配置好項目,然後輸入簡單的指令(如mvn clean install),Maven會幫我們處理那些煩瑣的任務。

                Maven是跨平台的,這意味着無論是在Windows上,還是在Linux或者Mac上,都可以使用同樣的指令。

                我們一直在不停地尋找避免重複的方法。設計的重複、編碼的重複、文檔的重複,當 然還有建構的重複。Maven最大化地消除了建構的重複,抽象了建構生命周期,并且為絕大部分的建構任務提供了已實作的插件,我們不再需要定義過程,甚至不需要再去實作這些過程中的一些任務。最簡單的例子是測試,我們沒必要告訴Maven去測試,更不需要告訴Maven如何運作測試,隻需要遵循Maven 的約定編寫好測試用例,當我們運作建構的時候,這些測試便會自動運作。

                想象一下,Maven抽象了一個完整的建構生命周期模型,這個模型吸取了大量其 他的建構腳本和建構工具的優點,總結了大量項目的實際需求。如果遵循這個模型,可以避免很多不必要的錯誤,可以直接使用大量成熟的Maven插件來完成我們的任務(很多時候我們可能都不知道自己在使用Maven插件)。此外,如果有非常特殊的需求,我們也可以輕松實作自己的插件。

                Maven還有一個優點,它能幫助我們标準化建構過程。在Maven之前,十個項目可能有十種建構方式;有了Maven之後,所有項目的建構指令都是簡單一緻的,這極大地避免了不必要的學習成本,而且有利于促進項目團隊的标準化。

                綜上所述,Maven作為一個建構工具,不僅能幫我們自動化建構,還能夠抽象建構過程,提供建構任務實作;它跨平台,對外提供了一緻的操作接口,這一切足以使它成為優秀的、流行的建構工具。

        1.3  Maven不僅僅是建構工具

                Java不僅是一門程式設計語言,還是一個平台,通過JRuby和Jython,我們可以在Java平台上編寫和運作Ruby和Python程式。我們也應該認識到,Maven不僅是建構工具,還是一個依賴管理工具和項目資訊管理工具。它提供了中央倉庫,能幫我們自動下載下傳構件。

                在這個開源的年代裡,幾乎任何Java應用都會借用一些第三方的開源類庫,這些 類庫都可通過依賴的方式引入到項目中來。随着依賴的增多,版本不一緻、版本沖突、依賴臃腫等問題都會接踵而來。手工解決這些問題是十分枯燥的,幸運的是 Maven提供了一個優秀的解決方案,它通過一個坐标系統準确地定位每一個構件(artifact),也就是通過一組坐标Maven能夠找到任何一個 Java類庫(如jar檔案)。Maven給這個類庫世界引入了經緯,讓它們變得有秩序,于是我們可以借助它來有序地管理依賴,輕松地解決那些繁雜的依賴問題。

                Maven還能幫助我們管理原本分散在項目中各個角落的項目資訊,包括項目描述、開發者清單、版本控制系統位址、許可證、缺陷管理系統位址等。這些微小的變化看起來很瑣碎,并不起眼,但卻在不知不覺中為我們節省了大量尋找資訊的時間。除了直接的項目資訊,通過Maven自動生成的站點,以及一些已有的插件,我們還能夠輕松獲得項目文檔、測試報告、靜态分析報告、源碼版本日志報告等非常具有價值的項目資訊。

                Maven還為全世界的Java開發者提供了一個免費的中央倉庫,在其中幾乎可以找到任何的流行開源類庫。通過一些Maven的衍生工具(如Nexus),我們還能對其進行快速地搜尋。隻要定位了坐标,Maven就能夠幫我們自動下載下傳,省去了手工勞動。

                使用Maven還能享受一個額外的好處,即Maven對于項目目錄結構、測試用 例命名方式等内容都有既定的規則,隻要遵循了這些成熟的規則,使用者在項目間切換的時候就免去了額外的學習成本,可以說是約定優于配置(Convention Over Configuration)。

二: 為什麼需要Maven 

        Maven不是Java領域唯一的建構管理的解決方案。本節将通過一些簡單的例子解釋Maven的必要性,并介紹其他建構解決方案,如IDE、Make和Ant,并将它們與Maven進行比較。

        2.1  組裝PC和品牌PC

                筆者國中時開始接觸計算機,到了高中時更是夢寐以求希望擁有一台自己的計算機。我的第一台計算機是賽揚733的,選購是一個漫長的過程,我先閱讀了大量的雜志以了解各類配件的優劣,CPU、記憶體、主機闆、顯示卡,甚至聲霸卡,我都仔細地挑選,後來還跑了很多商家,調貨、讨價還價,組裝好後自己裝作業系統和驅動程式……雖然這花費了我大量時間,但我很享受這個過程。可是事實證明,裝出來的機器穩定性不怎麼好。

                一年前我需要配一台工作站,這時候我已經沒有太多時間去研究電腦配件了。我選擇了某知名PC供應商的線上商店,大概浏覽了一下主流的機型,選擇了我需要的配置,然後下單、付款。接着PC供應商幫我組裝電腦、安裝作業系統和驅動程式。一周後,物流公司将電腦送到我的家裡,我接上顯示器、電源、滑鼠和鍵盤就能直接使用了。這為我節省了大量時間,而且這台電腦十分穩定,商家在把電腦發送給我之前已經進行了很好的測試。對了,我還能享受兩年的售後服務。

                使用腳本建立高度自定義的建構系統就像買組裝PC,耗時費力,結果也不一定很好。當然,你可以享受從無到有的樂趣,但恐怕實際項目中無法給你那麼多時間。使用Maven就像購買品牌PC,省時省力,并能得到成熟的建構系統,還能得到來自于Maven社群的大量支援。唯一與購買品牌PC不同的是,Maven是開源的,你無須為此付費。如果有興趣,你還能去了解Maven是如何工作的,而我們無法知道那些PC巨頭的商業秘密。

        2.2  IDE不是萬能的

                當然,我們無法否認優秀的IDE能大大提高開發效率。目前主流的IDE如Eclipse和NetBeans等都提供了強大的文本編輯、調試甚至重構功能。雖然使用簡單的文本編輯器和指令行也能完成絕大部分開發工作,但很少有人願意那樣做。然而,IDE是有其天生缺陷的:

                •     IDE依賴大量的手工操作。編譯、測試、代碼生成等工作都是互相獨立的,很難一鍵完成所有工作。手工勞動往往意味着低效,意味着容易出錯。

                •     很難在項目中統一所有的IDE配置,每個人都有自己的喜好。也正是由于這個原因,一個在機器A上可以成功運作的任務,到了機器B的IDE中可能就會失敗。

                我們應該合理利用IDE,而不是過多地依賴它。對于建構這樣的任務,在IDE中一次次地點選滑鼠是愚蠢的行為。Maven是這方面的專家,而且主流IDE都內建了Maven,我們可以在IDE中友善地運作Maven執行建構。

        2.3  Make

                Make也許是最早的建構工具,它由StuartFeldman于1977年在Bell實驗室建立。Stuart Feldman也是以于2003年獲得了ACM國際計算機組織頒發的軟體系統獎。目前Make有很多衍生實作,包括最流行的GNU Make和BSD Make,還有Windows平台的Microsoft nmake等。

                Make由一個名為Makefile的腳本檔案驅動,該檔案使用Make自己定義的文法格式。其基本組成部分為一系列規則(Rules),而每一條規則又包括目标(Target)、依賴(Prerequisite)和指令(Command)。Makefile的基本結構如下:

TARGET… : PREREQUISITE… 
COMMAND 
… 
… 
           

                Make通過一系列目标和依賴将整個建構過程串聯起來,同時利用本地指令完成每個目标的實際行為。Make的強大之處在于它可以利用所有系統的本地指令,尤其是UNIX/Linux系統,豐富的功能、強大的指令能夠幫助Make快速高效地完成任務。

                但是,Make将自己和作業系統綁定在一起了。也就是說,使用Make,就不能實作(至少很難)跨平台的建構,這對于Java來說是非常不友好的。此外,Makefile的文法也成問題,很多人抱怨Make建構失敗的原因往往是一個難以發現的空格或Tab使用錯誤。

        2.4  Ant

                Ant不是指螞蟻,而是意指“另一個整潔的工具”(Another Neat Tool),它最早用來建構著名的Tomcat,其作者James Duncan Davidson創作它的動機就是因為受不了Makefile的文法格式。我們可以将Ant看成是一個Java版本的Make,也正因為使用了Java,Ant是跨平台的。此外,Ant使用XML定義建構腳本,相對于Makefile來說,這也更加友好。

                與Make類似,Ant有一個建構腳本build.xml,如下所示:

<?xml version="1.0"?>
<project name="Hello"default="compile">
<target name="compile"description="compile the Java source code to class files">
<mkdir dir="classes"/>
<javac srcdir="."destdir="classes"/>
</target>
<target name="jar"depends="compile" description="create a Jar file ">
<jar destfile="hello.jar">
<fileset dir="classes"includes="**/*.class"/>
<manifest>
<attribute name="Main.Class"value="HelloProgram"/>
</manifest>
</jar>
</target>
</project>
           

                build.xml的基本結構也是目标(target)、依賴(depends),以及實作目标的任務。比如在上面的腳本中,jar目标用來建立應用程式jar檔案,該目标依賴于compile目标,後者執行的任務是建立一個名為classes的檔案夾,編譯目前目錄的java檔案至classes目錄。compile目标完成後,jar目标再執行自己的任務。Ant有大量内置的用Java實作的任務,這保證了其跨平台的特質,同時,Ant也有特殊的任務exec來執行本地指令。

                和Make一樣,Ant也都是過程式的,開發者顯式地指定每一個目标,以及完成該目标所需要執行的任務。針對每一個項目,開發者都需要重新編寫這一過程,這裡其實隐含着很大的重複。Maven是聲明式的,項目建構過程和過程各個階段所需的工作都由插件實作,并且大部分插件都是現成的,開發者隻需要聲明項目的基本元素,Maven就執行内置的、完整的建構過程。這在很大程度上消除了重複。

                Ant是沒有依賴管理的,是以很長一段時間Ant使用者都不得不手工管理依賴,這是一個令人頭疼的問題。幸運的是,Ant使用者現在可以借助Ivy管理依賴。而對于Maven使用者來說,依賴管理是理所當然的,Maven不僅内置了依賴管理,更有一個可能擁有全世界最多Java開源軟體包的中央倉庫,Maven使用者無須進行任何配置就可以直接享用。

2.5  不重複發明輪子

                小張是一家小型民營軟體公司的程式員,他所在的公司要開發一個新的Web項目。經過協商,決定使用Spring、iBatis和Tapstry。jar包去哪裡找呢?公司裡估計沒有人能把Spring、iBatis和Tapstry所使用的jar包一個不少地找出來。大家的做法是,先到Spring的站點上去找一個spring.with.dependencies,然後去iBatis的網站上把所有列出來的jar包下載下傳下來,對Tapstry、Apachecommons等執行同樣的操作。項目還沒有開始,WEB.INF/lib下已經有近百個jar包了,帶版本号的、不帶版本号的、有用的、沒用的、相沖突的,怎一個“亂”字了得!

                在項目開發過程中,小張不時地發現版本錯誤和版本沖突問題,他隻能硬着頭皮逐一解決。項目開發到一半,經理發現最終部署的應用的體積實在太大了,要求小張去掉一些沒用的jar包,于是小張隻能加班加點地一個個删……

                小張隐隐地覺得這些依賴需要一個架構或者系統來進行管理。

                小張喜歡學習流行的技術,前幾年Ant十分流行,他學了,并成為了公司這方面的專家。小張知道,Ant打包,無非就是建立目錄,複制檔案,編譯源代碼,使用一堆任務,如copydir、fileset、classpath、ref、target,然後再jar、zip、war,打包就成功了。

                項目經理發話了:“兄弟們,新項目來了,小張,你來寫Ant腳本!”

                “是,保證完成任務!”接着,小張繼續建立一個新的XML檔案。target clean; target compile; target jar; …… 不知道他是否想過,在他寫的這麼多的Ant腳本中,有多少是重複勞動,有多少代碼會在一個又一個項目中重制。既然都差不多,有些甚至完全相同,為什麼每次都要重新編寫?

                終于有一天,小張意識到了這個問題,想複用Ant腳本,于是在開會時他說:“以後就都用我這個規範的Ant腳本吧,新的項目隻要遵循我定義的目錄結構就可以了。”經理聽後覺得很有道理:“嗯,确實是個進步。”

                這時新來的研究所學生發言了:“經理,用Maven吧,這個在開源社群很流行,比Ant更友善。”小張一聽很驚訝,Maven真比自己的“規範化Ant”強大?其實他不知道自己隻是在重新發明輪子,Maven已經有一大把現成的插件,全世界都在用,你自己不用寫任何代碼!

                為什麼沒有人說“我自己寫的代碼最靈活,是以我不用Spring,我自己實作IoC;我不用Hibernate,我自己封裝JDBC”?

三:Maven與極限程式設計 

        極限程式設計(XP)是近些年在軟體行業紅得發紫的靈活開發方法,它強調擁抱變化。該軟體開發方法的創始人Kent Beck提出了XP所追求的價值、實施原則和推薦實踐。下面看一下Maven是如何适應XP的。

首先看一下Maven如何幫助XP團隊實作一些核心價值:

        •     簡單。Maven暴露了一組一緻、簡潔的操作接口,能幫助團隊成員從原來的高度自定義的、複雜的建構系統中解脫出來,使用Maven現有的成熟的、穩定的元件也能簡化建構系統的複雜度。

        •     交流與回報。與版本控制系統結合後,所有人都能執行最新的建構并快速得到回報。此外,自動生成的項目報告也能幫助成員了解項目的狀态,促進團隊的交流。

此外,Maven更能無縫地支援或者融入到一些主要的XP實踐中:

        •     測試驅動開發(TDD)。TDD強調測試先行,所有産品都應該由測試用例覆寫。而測試是Maven生命周期的最重要的組成部分之一,并且Maven有現成的成熟插件支援業界流行的測試架構,如JUnit和TestNG。

        •     十分鐘建構。十分鐘建構強調我們能夠随時快速地從源碼建構出最終的産品。這正是Maven所擅長的,隻需要一些配置,之後用一條簡單的指令就能讓Maven幫你清理、編譯、測試、打包、部署,然後得到最終的産品。

        •     持續內建(CI)。CI強調項目以很短的周期(如15分鐘)內建最新的代碼。 實際上,CI的前提是源碼管理系統和建構系統。目前業界流行的CI伺服器如Hudson和CruiseControl都能很好地和Maven進行內建。也就是說,使用Maven後,持續內建會變得更加友善。

        •     富有資訊的工作區。 這條實踐強調開發者能夠快速友善地了解到項目的最新狀态。當然,Maven并不會幫你把測試覆寫率報告貼到牆上,也不會在你的工作台上放個鴨子告訴你建構失敗了。不過使用Maven釋出的項目報告站點,并配置你需要的項目報告,如測試覆寫率報告,都能幫你把資訊推送到開發者眼前。

        上述這些實踐并非隻在XP中适用。事實上,除了其他靈活開發方法如SCRUM之外,幾乎任何軟體開發方法都能借鑒這些實踐。也就是說,Maven幾乎能夠很好地支援任何軟體開發方法。

        例 如,在傳統的瀑布模型開發中,項目依次要經曆需求開發、分析、設計、編碼、測試和內建釋出階段。從設計和編碼階段開始,就可以使用Maven來建立項目的建構系統。在設計階段,也完全可以針對設計開發測試用例,然後再編寫代碼來滿足這些測試用例。然而,有了自動化建構系統,我們可以節省很多手動的測試時間。此外,盡早地使用建構系統內建團隊的代碼,對項目也是百利而無一害。最後,Maven還能幫助我們快速地釋出項目。

     更多内容:maven學習筆記之——目錄