摘要:項(xiàng)目構(gòu)建基礎(chǔ)從屬于筆者的現(xiàn)代開發(fā)基礎(chǔ)系列文章,介紹了的歷史背景與多種構(gòu)建工具對(duì)比,以及的基本配置安裝與使用本文涉及的參考資料聲明在學(xué)習(xí)與實(shí)踐資料索引以及學(xué)習(xí)與資料索引。
MavenMaven 項(xiàng)目構(gòu)建基礎(chǔ)從屬于筆者的現(xiàn)代 Java 開發(fā)基礎(chǔ)系列文章,介紹了 Maven 的歷史背景與多種構(gòu)建工具對(duì)比,以及 Maven 的基本配置安裝與使用;本文涉及的參考資料聲明在 Java 學(xué)習(xí)與實(shí)踐資料索引以及 Maven 學(xué)習(xí)與資料索引。本文整理時(shí)間也較早,最近因?yàn)檎?Java 相關(guān)的資料所以重新歸納了下。
Maven 是功能強(qiáng)大的構(gòu)建工具能夠幫我們自動(dòng)化構(gòu)建過程,從清理、編譯、測(cè)試到生成報(bào)告,再到打包和部署。我們只需要輸入簡(jiǎn)單的命令(如 mvn clean install),Maven 就會(huì)幫我們處理繁瑣的任務(wù);它最大化的消除了構(gòu)建的重復(fù),抽象了構(gòu)建生命周期,并且為絕大部分的構(gòu)建任務(wù)提供了已實(shí)現(xiàn)的插件。比如說測(cè)試,我們只需要遵循 Maven 的約定編寫好測(cè)試用例,當(dāng)我們運(yùn)行構(gòu)建的時(shí)候,這些測(cè)試便會(huì)自動(dòng)運(yùn)行。除此之外,Maven 能幫助我們標(biāo)準(zhǔn)化構(gòu)建過程。在 Maven 之前,十個(gè)項(xiàng)目可能有十種構(gòu)建方式,但通過 Maven,所有項(xiàng)目的構(gòu)建命令都是簡(jiǎn)單一致的。有利于促進(jìn)項(xiàng)目團(tuán)隊(duì)的標(biāo)準(zhǔn)化。
構(gòu)建工具對(duì)比Maven 是筆者接觸的第一個(gè)脫離于 IDE 的命令行構(gòu)建工具,筆者之前一直是基于 Visual Studio 下進(jìn)行 Windows 驅(qū)動(dòng)開發(fā),并不是很能明白 Builder 與 IDE 之間的區(qū)別。依賴大量的手工操作。編譯、測(cè)試、代碼生成等工作都是相互獨(dú)立的,很難一鍵完成所有工作。手工勞動(dòng)往往意味著低效,意味著容易出錯(cuò)。很難在項(xiàng)目中統(tǒng)一所有的 IDE 配置,每個(gè)人都有自己的喜好。也正是由于這個(gè)原因,一個(gè)在機(jī)器 A 上可以成功運(yùn)行的任務(wù),到了機(jī)器 B 的 IDE 中可能就會(huì)失敗。
在 Linux C 開發(fā)中我們常常使用 Make 進(jìn)行構(gòu)建,不過 Make 將自己和操作系統(tǒng)綁定在一起了;也就是說,使用Make,就不能實(shí)現(xiàn)(至少很難)跨平臺(tái)的構(gòu)建,這對(duì)于Java來說是非常不友好的。此外,Makefile 的語法也成問題,很多人抱怨 Make 構(gòu)建失敗的原因往往是一個(gè)難以發(fā)現(xiàn)的空格或 Tab 使用錯(cuò)誤。而在 Java 發(fā)展過程中常見的自動(dòng)化構(gòu)建工具以 Ant、Maven、Gradle 為代表,整個(gè)自動(dòng)化流程往往包含以下步驟:編譯源代碼、運(yùn)行單元測(cè)試和集成測(cè)試、執(zhí)行靜態(tài)代碼分析、生成分析報(bào)告、創(chuàng)建發(fā)布版本、部署到目標(biāo)環(huán)境、部署傳遞過程以及執(zhí)行冒煙測(cè)試和自動(dòng)功能測(cè)試。
和 Make 一樣,Ant 也都是過程式的,開發(fā)者顯式地指定每一個(gè)目標(biāo),以及完成該目標(biāo)所需要執(zhí)行的任務(wù)。針對(duì)每一個(gè)項(xiàng)目,開發(fā)者都需要重新編寫這一過程,這里其實(shí)隱含著很大的重復(fù)。Maven 是聲明式的,項(xiàng)目構(gòu)建過程和過程各個(gè)階段所需的工作都由插件實(shí)現(xiàn),并且大部分插件都是現(xiàn)成的,開發(fā)者只需要聲明項(xiàng)目的基本元素,Maven 就執(zhí)行內(nèi)置的、完整的構(gòu)建過程。這在很大程度上消除了重復(fù)。
此外,Ant 是沒有依賴管理的,所以很長(zhǎng)一段時(shí)間 Ant 用戶都不得不手工管理依賴,這是一個(gè)令人頭疼的問題。幸運(yùn)的是,Ant 用戶現(xiàn)在可以借助 Ivy 管理依賴。而對(duì)于 Maven 用戶來說,依賴管理是理所當(dāng)然的,Maven 不僅內(nèi)置了依賴管理,更有一個(gè)可能擁有全世界最多 Java 開源軟件包的中央倉庫,Maven 用戶無須進(jìn)行任何配置就可以直接享用。
而 Gradle 拋棄了 Maven 的基于 XML 的繁瑣配置;眾所周知 XML 的閱讀體驗(yàn)比較差,對(duì)于機(jī)器來說雖然容易識(shí)別,但畢竟是由人去維護(hù)的。取而代之的是 Gradle 采用了領(lǐng)域特定語言 Groovy 的配置,大大簡(jiǎn)化了構(gòu)建代碼的行數(shù)。Maven 的設(shè)計(jì)核心 Convention Over Configuration 被 Gradle 更加發(fā)揚(yáng)光大,而 Gradle 的配置即代碼又超越了Maven。在 Gradle 中任何配置都可以作為代碼被執(zhí)行的,我們也可以隨時(shí)使用已有的 Ant 腳本(Ant task 是 Gradle 中的一等公民)、Java 類庫、Groovy 類庫來輔助完成構(gòu)建任務(wù)的編寫。在現(xiàn)代 Java 開發(fā)基礎(chǔ)系列文章中也有專門的章節(jié)講解 Gradle,筆者在 Android 與 Spring 項(xiàng)目構(gòu)建中也會(huì)優(yōu)先選擇 Gradle。
環(huán)境配置Maven 的安裝也非常方便,可從 Apache 官方下載最新的 Maven 壓縮包然后解壓,也可以使用 SDK Man 執(zhí)行安裝;如果是手動(dòng)配置的話我們還需要配置設(shè)置下系統(tǒng)的環(huán)境變量:
M2HOME: 指向Maven安裝目錄
Path: 追加 Maven 安裝目錄下的 bin 目錄
在用戶目錄下,我們可以發(fā)現(xiàn) .m2 文件夾。默認(rèn)情況下,該文件夾下放置了 Maven 本地倉庫 .m2/repository。所有的 Maven 構(gòu)件(artifact)都被存儲(chǔ)到該倉庫中,以方便重用。默認(rèn)情況下,~/.m2 目錄下除了 repository 倉庫之外就沒有其他目錄和文件了,不過大多數(shù) Maven 用戶需要復(fù)制 M2HOME/conf/settings.xml 文件到 ~/.m2/settings.xml。
部分常用的Maven命令如下:
mvn -v # 查看maven版本 mvn compile # 編譯 mvn test # 測(cè)試 mvn package # 打包 mvn clean # 刪除 target mvn install # 安裝jar包到本地倉庫中 mvn archetype:generate -DgroupId=co.hoteam -DartifactId=Zigbee -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false # 創(chuàng)建一個(gè)新工程網(wǎng)絡(luò)代理
眾所周知的原因,國(guó)內(nèi)有時(shí)候并不能夠很順暢的訪問 Maven 的中央倉庫,往往我們需要訪問國(guó)內(nèi)的鏡像地址:
CN OSChina Central http://maven.oschina.net/content/groups/public/ central
或者編輯 ~/.m2/settings.xml 文件(如果沒有該文件,則復(fù)制 $M2HOME/conf/settings.xml),添加代理配置如下:
... ... my-proxy true http 代理服務(wù)器主機(jī)名 端口號(hào)
如果不行試試重啟機(jī)器或者eclipse等ide還不行試試下面這種方式:windows-->preferences-->maven-->installations add
這樣配置后將使用指定目錄下的maven,而非eclipse的maven內(nèi)置插件。
其他錯(cuò)誤處理(1)有時(shí)候執(zhí)行mvn compile時(shí)候會(huì)爆出無法找到j(luò)unit的錯(cuò)誤,可能的解決方法有:
在Eclipse的Projects選項(xiàng)中使用Projects Clean
在pom.xml中引入junit依賴項(xiàng),并且保證其scope為compile:
junit junit 4.11 test
(2)有時(shí)候在Eclipse下執(zhí)行mvn compile或者相關(guān)命令時(shí),會(huì)報(bào)某某文件出現(xiàn)不識(shí)別字符或者非UTF-8編碼,此時(shí)可以做幾步檢查:
檢查對(duì)應(yīng)的Java文件是否有Bom頭
檢查對(duì)應(yīng)的Java文件的編碼
如果都沒有問題,在Eclipse中先將文件編碼設(shè)置為GBK,再改回UTF-8試試。
項(xiàng)目配置就像 Make 的 Makefile,Ant 的 build.xml 一樣,Maven 項(xiàng)目的核心是 pom.xml。首先創(chuàng)建一個(gè)名為 hello-world 的文件夾,打開該文件夾,新建一個(gè)名為 pom.xml 的文件,輸入其內(nèi)容如下:
文件結(jié)構(gòu)4.0.0 com.wx.mvn hello-world 1.0-SNAPSHOT Maven Hello World Project
代碼的第一行是 XML 頭,指定了該 xml 文檔的版本和編碼方式。緊接著是 project 元素,project 是所有 pom.xml 的根元素,它還聲明了一些 POM 相關(guān)的命名空間及 xsd 元素,雖然這些屬性不是必須的,但使用這些屬性能夠讓第三方工具(如 IDE 中的 XML 編輯器)幫助我們快速編輯 POM。
根元素下的第一個(gè)子元素 modelVersion 指定了當(dāng)前 POM 模型的版本,對(duì)于 Maven 2 及 Maven 3 來說,它只能是4.0.0。這段代碼中最重要的是 groupId,artifactId 和 version 三行。這三個(gè)元素定義了一個(gè)項(xiàng)目基本的坐標(biāo),在Maven 的世界,任何的 jar、pom 或者 war 都是以基于這些基本的坐標(biāo)進(jìn)行區(qū)分的。
groupId 定義了項(xiàng)目屬于哪個(gè)組,這個(gè)組往往和項(xiàng)目所在的組織或公司存在關(guān)聯(lián),譬如你在 googlecode 上建立了一個(gè)名為 myapp 的項(xiàng)目,那么 groupId 就應(yīng)該是 com.googlecode.myapp,如果你的公司是 mycom,有一個(gè)項(xiàng)目為 myapp,那么 groupId 就應(yīng)該是 com.mycom.myapp。
artifactId 定義了當(dāng)前 Maven 項(xiàng)目在組中唯一的 ID,我們?yōu)檫@個(gè) Hello World 項(xiàng)目定義 artifactId 為 hello-world,本書其他章節(jié)代碼會(huì)被分配其他的 artifactId。而在前面的 groupId 為 com.googlecode.myapp 的例子中,你可能會(huì)為不同的子項(xiàng)目(模塊)分配 artifactId,如:myapp-util、myapp-domain、myapp-web 等等。
version 指定了 Hello World 項(xiàng)目當(dāng)前的版本——1.0-SNAPSHOT。SNAPSHOT 意為快照,說明該項(xiàng)目還處于開發(fā)中,是不穩(wěn)定的版本。隨著項(xiàng)目的發(fā)展,version 會(huì)不斷更新,如升級(jí)為 1.0、1.1-SNAPSHOT、1.1、2.0 等等。
最后一個(gè) name 元素聲明了一個(gè)對(duì)于用戶更為友好的項(xiàng)目名稱,雖然這不是必須的,但我還是推薦為每個(gè) POM 聲明 name,以方便信息交流。 沒有任何實(shí)際的 Java 代碼,我們就能夠定義一個(gè) Maven 項(xiàng)目的 POM,這體現(xiàn)了 Maven 的一大優(yōu)點(diǎn),它能讓項(xiàng)目對(duì)象模型最大程度地與實(shí)際代碼相獨(dú)立,我們可以稱之為解耦,或者正交性,這在很大程度上避免了 Java 代碼和 POM 代碼的相互影響。比如當(dāng)項(xiàng)目需要升級(jí)版本時(shí),只需要修改 POM,而不需要更改 Java 代碼;而在 POM 穩(wěn)定之后,日常的 Java 代碼開發(fā)工作基本不涉及 POM 的修改。
變量替換在 pom.xml 定義 properties 標(biāo)簽
UTF-8 1.2.6
以上內(nèi)容就改成了
org.springframework spring-core ${spring.version} org.springframework spring-aop ${spring.version}
也可以使用 maven-properties 插件來支持外部變量
目錄結(jié)構(gòu)項(xiàng)目主代碼和測(cè)試代碼不同,項(xiàng)目的主代碼會(huì)被打包到最終的構(gòu)件中(比如 jar),而測(cè)試代碼只在運(yùn)行測(cè)試時(shí)用到,不會(huì)被打包。默認(rèn)情況下,Maven 假設(shè)項(xiàng)目主代碼位于 src/main/java 目錄,我們遵循 Maven 的約定,創(chuàng)建該目錄,然后在該目錄下創(chuàng)建文件 com/wx/mvn/helloworld/HelloWorld.java,其內(nèi)容如下:
package com.wx.mvn.helloworld; public class HelloWorld { public String sayHello() { return "Hello Maven"; } public static void main(String[] args) { System.out.print( new HelloWorld().sayHello() ); } }
關(guān)于該 Java 代碼有兩點(diǎn)需要注意。首先,大部分情況下我們應(yīng)該把項(xiàng)目主代碼放到 src/main/java/ 目錄下(遵循Maven的約定),而無須額外的配置,Maven 會(huì)自動(dòng)搜尋該目錄找到項(xiàng)目主代碼。其次,該 Java 類的包名是 com.wx.mvn.helloworld,這與我們之前在 POM 中定義的 groupId 和 artifactId 相吻合。一般來說,項(xiàng)目中 Java 類的包都應(yīng)該基于項(xiàng)目的 groupId 和 artifactId,這樣更加清晰,更加符合邏輯,也方便搜索構(gòu)件或者 Java 類。 代碼編寫完畢后,我們使用 Maven 進(jìn)行編譯,在項(xiàng)目根目錄下運(yùn)行命令 mvn clean compile 即可。Maven 首先執(zhí)行了clean:clean 任務(wù),刪除 target/ 目錄,默認(rèn)情況下 Maven 構(gòu)建的所有輸出都在 target/ 目錄中;接著執(zhí)行 resources:resources 任務(wù)(未定義項(xiàng)目資源,暫且略過);最后執(zhí)行 compiler:compile 任務(wù),將項(xiàng)目主代碼編譯至 target/classes 目錄(編譯好的類為 com/wx/mvn/helloworld/HelloWorld.Class)。
倉庫配置下面介紹一些 Maven 倉庫工作的原理。典型的一個(gè) Maven依賴下會(huì)有這三個(gè)文件:
maven-metadata.xml maven-metadata.xml.md5 maven-metadata.xml.sha1
maven-metadata.xml里面記錄了最后deploy的版本和時(shí)間。
io.github.hengyunabc mybatis-ehcache-spring 0.0.1-SNAPSHOT 20150804.095005 1 20150804095005
其中 md5, sha1 校驗(yàn)文件是用來保證這個(gè) meta 文件的完整性。Maven 在編繹項(xiàng)目時(shí),會(huì)先嘗試請(qǐng)求 maven-metadata.xml,如果沒有找到,則會(huì)直接嘗試請(qǐng)求到j(luò)ar文件,在下載 jar 文件時(shí)也會(huì)嘗試下載 jar 的 md5, sha1 文件。Maven 的 repository 并沒有優(yōu)先級(jí)的配置,也不能多帶帶為某些依賴配置 repository。所以如果項(xiàng)目配置了多個(gè)repository,在首次編繹時(shí),會(huì)依次嘗試下載依賴。如果沒有找到,嘗試下一個(gè),整個(gè)流程會(huì)很長(zhǎng)。所以盡量多個(gè)依賴放同一個(gè)倉庫,不要每個(gè)項(xiàng)目都有一個(gè)自己的倉庫。如果想要使用本地file倉庫里,在項(xiàng)目的pom.xml里配置,如:
延伸閱讀hengyunabc-maven-repo file:/home/hengyunabc/code/maven-repo/repository/
Java 時(shí)間與日期處理
垃圾回收算法與 JVM 垃圾回收器綜述
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67562.html
摘要:編寫一個(gè)接口創(chuàng)建命名為根據(jù)實(shí)際情況修改創(chuàng)建類,內(nèi)容如下啟動(dòng)主程序,使用等工具發(fā)起請(qǐng)求,可以看到頁面返回編寫單元測(cè)試用例打開的下的測(cè)試入口類。 簡(jiǎn)介 在您第1次接觸和學(xué)習(xí)Spring框架的時(shí)候,是否因?yàn)槠浞彪s的配置而退卻了?在你第n次使用Spring框架的時(shí)候,是否覺得一堆反復(fù)黏貼的配置有一些厭煩?那么您就不妨來試試使用Spring Boot來讓你更易上手,更簡(jiǎn)單快捷地構(gòu)建Spring應(yīng)...
摘要:基本配置環(huán)境變量環(huán)境變量中添加為主目錄在中添加使用阿里云中央倉庫修改根目錄下文件夾中的文件,內(nèi)容如下創(chuàng)建基于的項(xiàng)目使用命令行創(chuàng)建使用原型插件創(chuàng)建工程。 「博客搬家」 原地址: 簡(jiǎn)書 原發(fā)表時(shí)間: 2017-03-23 Maven 是基于項(xiàng)目對(duì)象模型「POM」,可以通過一小段描述信息來管理項(xiàng)目的構(gòu)建、報(bào)告和文檔的軟件項(xiàng)目管理工具。本文總結(jié)了 Maven 的基本用法。 1. Maven...
摘要:要從頭開始,請(qǐng)繼續(xù)使用構(gòu)建?,F(xiàn)在您已經(jīng)準(zhǔn)備好使用構(gòu)建項(xiàng)目,下一步是安裝。項(xiàng)目使用名為的文件定義。項(xiàng)目所屬的組或組織。默認(rèn)情況下,所有依賴項(xiàng)都作為依賴項(xiàng)確定范圍。概要恭喜您已經(jīng)為構(gòu)建項(xiàng)目創(chuàng)建了一個(gè)簡(jiǎn)單而有效的項(xiàng)目定義。 本指南將指導(dǎo)您使用Maven構(gòu)建一個(gè)簡(jiǎn)單的Java項(xiàng)目。 你要構(gòu)建什么 您將創(chuàng)建一個(gè)提供一天中時(shí)間的應(yīng)用程序,然后使用Maven構(gòu)建它。 你需要什么 大約15分鐘 最喜...
摘要:在年下旬開源了一款新的工具,可以輕松地將應(yīng)用程序容器化。由于默認(rèn)訪問谷歌的倉庫,而國(guó)內(nèi)訪問不穩(wěn)定會(huì)經(jīng)常導(dǎo)致網(wǎng)絡(luò)超時(shí),所以筆者使用了國(guó)內(nèi)的阿里云鏡像服務(wù),那么就不需要訪問谷歌的倉庫了。執(zhí)行完成后,我們可以在阿里云鏡像倉庫獲取鏡像。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 歡迎關(guān)注公眾號(hào):「服務(wù)端思維」。一群同頻者,一起成長(zhǎng),一起精進(jìn),打破認(rèn)知的局限性。...
摘要:在年下旬開源了一款新的工具,可以輕松地將應(yīng)用程序容器化。由于默認(rèn)訪問谷歌的倉庫,而國(guó)內(nèi)訪問不穩(wěn)定會(huì)經(jīng)常導(dǎo)致網(wǎng)絡(luò)超時(shí),所以筆者使用了國(guó)內(nèi)的阿里云鏡像服務(wù),那么就不需要訪問谷歌的倉庫了。執(zhí)行完成后,我們可以在阿里云鏡像倉庫獲取鏡像。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 歡迎關(guān)注公眾號(hào):「服務(wù)端思維」。一群同頻者,一起成長(zhǎng),一起精進(jìn),打破認(rèn)知的局限性。...
閱讀 1140·2021-11-24 09:38
閱讀 3245·2021-11-19 09:56
閱讀 2968·2021-11-18 10:02
閱讀 737·2019-08-29 12:50
閱讀 2575·2019-08-28 18:30
閱讀 873·2019-08-28 18:10
閱讀 3678·2019-08-26 11:36
閱讀 2653·2019-08-23 18:23