讀古今文學網 > Maven實戰 > 7.1 何為生命週期 >

7.1 何為生命週期

在Maven出現之前,項目構建的生命週期就已經存在,軟件開發人員每天都在對項目進行清理、編譯、測試及部署。雖然大家都在不停地做構建工作,但公司和公司間、項目和項目間,往往使用不同的方式做類似的工作。有的項目以手工的方式在執行編譯測試,有的項目寫了自動化腳本執行編譯測試。可以想像的是,雖然各種手工方式十分類似,但不可能完全一樣;同樣地,對於自動化腳本,大家也是各寫各的,能滿足自身需求即可,換個項目就需要重頭再來。

Maven的生命週期就是為了對所有的構建過程進行抽像和統一。Maven從大量項目和構建工具中學習和反思,然後總結了一套高度完善的、易擴展的生命週期。這個生命週期包含了項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎所有構建步驟。也就是說,幾乎所有項目的構建,都能映射到這樣一個生命週期上。

Maven的生命週期是抽像的,這意味著生命週期本身不做任何實際的工作,在Maven的設計中,實際的任務(如編譯源代碼)都交由插件來完成。這種思想與設計模式中的模板方法(Template Method)非常相似。模板方法模式在父類中定義算法的整體結構,子類可以通過實現或者重寫父類的方法來控制實際的行為,這樣既保證了算法有足夠的可擴展性,又能夠嚴格控制算法的整體結構。如下的模板方法抽像類能夠很好地體現Maven生命週期的概念,見代碼清單7-1。

代碼清單7-1 模擬生命週期的模板方法抽像類

這段代碼非常簡單,build()方法定義了整個構建的過程,依次初始化、編譯、測試、打包(由於package與Java關鍵字衝突,這裡使用了單詞packagee)、集成測試和部署,但是這個類中沒有具體實現初始化、編譯、測試等行為,它們都交由子類去實現。

雖然上述代碼和Maven實際代碼相去甚遠,Maven的生命週期包含更多的步驟和更複雜的邏輯,但它們的基本理念是相同的。生命週期抽像了構建的各個步驟,定義了它們的次序,但沒有提供具體實現。那麼誰來實現這些步驟呢?不能讓用戶為了編譯而寫一堆代碼,為了測試又寫一堆代碼,那不就成了大家在重複發明輪子嗎?Maven當然必須考慮這一點,因此它設計了插件機制。每個構建步驟都可以綁定一個或者多個插件行為,而且Maven為大多數構建步驟編寫並綁定了默認插件。例如,針對編譯的插件有maven-compiler-plugin,針對測試的插件有maven-surefire-plugin等。雖然在大多數時間裡,用戶幾乎都不會覺察到插件的存在,但實際上編譯是由maven-compiler-plugin完成的,而測試是由maven-surefire-plugin完成的。當用戶有特殊需要的時候,也可以配置插件定制構建行為,甚至自己編寫插件。生命週期和插件的關係如圖7-1所示。

圖7-1 生命週期和插件的關係

Maven定義的生命週期和插件機制一方面保證了所有Maven項目有一致的構建標準,另一方面又通過默認插件簡化和穩定了實際項目的構建。此外,該機制還提供了足夠的擴展空間,用戶可以通過配置現有插件或者自行編寫插件來自定義構建行為。