1.maven package和maven install 有什麼區別?
2.你常用的maven命令有哪些?
3.dependencyManagement> 是幹什麼的?
4.還有用過其它構建工具嗎? 和maven有啥區別?
這幾個問題都可以脫口而出,你應該是有點 maven 能耐,寫代碼去吧,不用看了
1.Maven是啥:
Maven是Apache軟件基金會唯一維護的一款自動化構建工具,專注於服務Java平臺的項目構建和依賴管理。
Maven是基於項目對象模型(POM),可以通過一小段描述信息來管理項目的構建、報告和文檔的軟件項目管理工具。
2.Maven可以幹啥:
- 添加第三方jar包
- jar包之間的依賴關係: Maven 可以替我們自動的將當前 jar 包所依賴的其他所有 jar 包全部導入進來
- 獲取第三方jar包: Maven 提供了一個完全統一規範的 jar 包管理體系,只需要在項目中以座標的方式依賴一個 jar 包,Maven 就會自動從中央倉庫進行下載到本地倉庫
- 將項目拆分成多個工程模塊
- 構建項目(打包,編譯等)
3.構建項目的幾個主要環節:
- 清理(clean):刪除以前的編譯結果,為重新編譯做好準備
- 編譯(compile):將Java 源程序編譯為字節碼文件
- 測試(test):針對項目中的關鍵點進行測試,確保項目在迭代開發過程中關鍵點的正確性
- 報告:在每一次測試後以標準的格式記錄和展示測試結果
- 打包(package):將一個包含諸多文件的工程封裝為一個壓縮文件用於安裝或部署。Java 工程對應 jar 包,Web工程對應 war 包。
- 安裝(install):在 Maven 環境下特指將打包的結果——jar 包或 war 包安裝到本地倉庫中。
- 部署(deploy):將打包的結果部署到遠程倉庫或將 war 包部署到服務器上運行。
4.Maven常用命令
- mvn -version/-v —— 顯示版本信息
- mvn clean —— 清空生成的文件
- mvn compile —— 編譯
- mvn test —— 編譯並測試
- mvn package —— 生成target目錄,編譯、測試代碼,生成測試報告,生成jar/war文件
- mvn site —— 生成項目相關信息的網站
- mvn clean compile —— 表示先運行清理之後運行編譯,會將代碼編譯到target文件夾中
- mvn clean package —— 運行清理和打包
- mvn clean install —— 運行清理和安裝,會將打好的包安裝到本地倉庫中,以便其他的項目可以調用
- mvn clean deploy —— 運行清理和發佈
5.Maven核心概念
Maven 能夠實現自動化構建是和它的內部原理分不開的,這裡我們從 Maven 的九個核心概念入手, 看看 Maven 是如何實現自動化構建的
- POM
- 約定的目錄結構
- 座標
- 依賴管理
- 倉庫管理
- 生命週期
- 插件和目標
- 繼承
- 聚合
Maven 的核心程序中僅僅定義了抽象的生命週期,而具體的操作則是由 Maven 的插件來完成的。可是 Maven 的插件並不包含在 Maven 的核心程序中,在首次使用時需要聯網下載。 下載得到的插件會被保存到本地倉庫中。本地倉庫默認的位置是:~.m2\\repository。
5.1. Maven約定的工程目錄:
Java開發領域普遍認同的一個觀點:約定>配置>編碼(能用配置解決的問題就不編碼,能基於約定的就不配置)
5.2. POM
Project Object Model:項目對象模型。將 Java 工程的相關信息封裝為對象作為便於操作和管理的模型。
Maven 工程的核心配置。
5.3. 座標
- Maven 的座標 使用如下三個向量在 Maven 的倉庫中唯一的確定一個 Maven 工程。
- groupid:公司或組織的域名倒序+當前項目名稱artifactId:當前項目的模塊名稱version:當前模塊的版本
<code> <groupid>net.lazyegg.maven/<groupid>
<artifactid>Hello/<artifactid>
<version>0.0.1-SNAPSHOT/<version>
/<code>
- 如何通過座標到倉庫中查找 jar 包?將 gav 三個向量連起來net.lazyegg.maven+Hello+0.0.1-SNAPSHOT 以連起來的字符串作為目錄結構到倉庫中查找net/lazyegg/maven/Hello/0.0.1-SNAPSHOT/Hello-0.0.1-SNAPSHOT.jar
※ 注意:我們自己的 Maven 工程必須執行安裝操作才會進入倉庫。安裝的命令是:mvn install
5.4. 依賴
Maven 中最關鍵的部分,我們使用 Maven 最主要的就是使用它的依賴管理功能。要理解和掌握 Maven 的依賴管理,我們只需要解決以下幾個問題:
① 依賴的目的是什麼
當 A jar 包用到了 B jar 包中的某些類時,A 就對 B 產生了依賴,這是概念上的描述。那麼如何在項目中以依賴的方式引入一個我們需要的 jar 包呢? 答案非常簡單,就是使用 dependency 標籤指定被依賴 jar 包的座標就可以了。
<code><dependency>
<groupid>net.lazyegg.maven/<groupid>
<artifactid>Hello/<artifactid>
<version>0.0.1-SNAPSHOT/<version>
<scope>compile/<scope>
/<dependency>
/<code>
② 依賴的範圍
有時依賴信息中除了目標 jar 包的座標還有一個 scope 設置,這就是依賴的範圍。依賴的範圍有幾個可選值,常用的有:compile、test、provided 三個,當然還有不常用的 runtime、system..
- compile:默認範圍,編譯測試運行都有效
- provided:在編譯和測試時有效
- runtime:在測試和運行時有效
- test:只在測試時有效
- system:在編譯和測試時有效,與本機系統關聯,可移植性差
- 常用依賴範圍有效性總結
compiletestprovided主程序√×√測試程序√√√參與部署√××
③ 依賴的傳遞性
A 依賴 B,B 依賴 C,A 能否使用 C 呢?那要看 B 依賴 C 的範圍是不是 compile,如果是則可用,否則不可用。
④ 依賴的排除
如果我們在當前工程中引入了一個依賴是 A,而 A 又依賴了 B,那麼 Maven 會自動將 A 依賴的 B 引入當 前工程,但是個別情況下 B 有可能是一個不穩定版,或對當前工程有不良影響。這時我們可以在引入 A 的時候將 B 排除。
<code><dependency>
<groupid>net.lazyegg.maven/<groupid>
<artifactid>Hello/<artifactid>
<version>0.0.1-SNAPSHOT/<version>
<scope>compile/<scope>
<exclusions>
<exclusion>
<groupid>commons-logging/<groupid>
<artifactid>commons-logging/<artifactid>
/<exclusion>
/<exclusions>
/<dependency>
/<code>
⑤ 統一管理所依賴 jar 包的版本,對同一個框架的一組 jar 包最好使用相同的版本。為了方便升級框架,可以將 jar 包的版本信息統一提取出來
- 統一聲明版本號
<code><properties>
<starfish.spring.version>4.1.1.RELEASE/<starfish.spring.version>
<project.build.sourceencoding>UTF-8/<project.build.sourceencoding>
/<properties>
/<code>
- 引用前面聲明的版本號
<code><dependency>
<groupid>org.springframework/<groupid>
<artifactid>spring-core/<artifactid>
<version>${starfish.spring.version}/<version>
<scope>compile/<scope>
/<dependency>
/<code>
⑥ 依賴的原則:解決 jar 包衝突
- 路徑最短者優先
- 路徑相同時先聲明者優先
項目版本衝突時候的那種蛋疼的感覺,只有疼過的才知道,所以,我們來看看疼過的人是怎麼解決的,推薦一個IDEA插件,Maven Helper,比自帶的好用,一目瞭然
image.png
5.5. 倉庫
- 分類本地倉庫:為當前本機電腦上的所有 Maven 工程服務遠程倉庫私服:架設在當前局域網環境下,為當前局域網範圍內的所有 Maven 工程服務中央倉庫:架設在 Internet 上,為全世界所有 Maven 工程服務中央倉庫的鏡像:架設在各個大洲,為中央倉庫分擔流量。減輕中央倉庫的壓力,同時更快的響應用戶請求,比如阿里的鏡像
- 倉庫中的文件Maven 的插件我們自己開發的項目的模塊第三方框架或工具的 jar 包 ※ 不管是什麼樣的 jar 包,在倉庫中都是按照座標生成目錄結構,所以可以通過統一的方式查詢或依賴,查詢地址:mvnrepository.com/
5.6. 生命週期
5.6.1. 什麼是 Maven 的生命週期?
Maven 生命週期定義了各個構建環節的執行順序,有了這個清單,Maven 就可以自動化的執行構建命令了。
Maven 有三套相互獨立的生命週期,分別是:
- Clean Lifecycle 在進行真正的構建之前進行一些清理工作
- Default Lifecycle 構建的核心部分,編譯,測試,打包,安裝,部署等等
- Site Lifecycle 生成項目報告,站點,發佈站點
它們是相互獨立的,你可以僅僅調用 clean 來清理工作目錄,僅僅調用 site 來生成站點。當然你也可以直接運行 mvn clean install site 運行所有這三套生命週期。 每套生命週期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應於一個特定的階段。比 如,運行 mvn clean,這個 clean 是 Clean 生命週期的一個階段。有 Clean 生命週期,也有 clean 階段。
5.6.2. Clean 生命週期
Clean 生命週期一共包含了三個階段:
- pre-clean 執行一些需要在 clean 之前完成的工作
- clean 移除所有上一次構建生成的文件
- post-clean 執行一些需要在 clean 之後立刻完成的工作
5.6.3. Site 生命週期
- pre-site 執行一些需要在生成站點文檔之前完成的工作
- site 生成項目的站點文檔
- post-site 執行一些需要在生成站點文檔之後完成的工作,並且為部署做準備
- site-deploy 將生成的站點文檔部署到特定的服務器上 這裡經常用到的是 site 階段和 site-deploy 階段,用以生成和發佈 Maven 站點,這可是 Maven 相當強大 的功能,Manager 比較喜歡,文檔及統計數據自動生成,很好看。
5.6.4. Default 生命週期
Default 生命週期是 Maven 生命週期中最重要的一個,絕大部分工作都發生在這個生命週期中(列出一些重要階段)
- validate:驗證工程是否正確,所有需要的資源是否可用。
- compile:編譯項目的源代碼。
- test:使用合適的單元測試框架來測試已編譯的源代碼。這些測試不需要已打包和佈署。
- package:把已編譯的代碼打包成可發佈的格式,比如 jar、war 等。
- integration-test:如有需要,將包處理和發佈到一個能夠進行集成測試的環境。
- verify:運行所有檢查,驗證包是否有效且達到質量標準。
- install:把包安裝到maven本地倉庫,可以被其他工程作為依賴來使用。
- deploy:在集成或者發佈環境下執行,將最終版本的包拷貝到遠程的repository,使得其他的開發者或者工程可以共享
5.6.5. 生命週期與自動化構建
運行任何一個階段的時候,它前面的所有階段都會被運行,例如我們運行 mvn install 的時候,代碼會被編譯,測試,打包。這就是 Maven 為什麼能夠自動執行構建過程的各個環節的原因。此外,Maven 的插件機制是完全依賴 Maven 的生命週期的,因此理解生命週期至關重要。
5.7. 插件和目標
- Maven 的核心僅僅定義了抽象的生命週期,具體的任務都是交由插件完成的
- 每個插件都能實現多個功能,每個功能就是一個插件目標
- Maven 的生命週期與插件目標相互綁定,以完成某個具體的構建任務 例如:compile 就是插件 maven-compiler-plugin 的一個目標;pre-clean 是插件 maven-clean-plugin 的一個目標
5.8. 繼承
- 為什麼需要繼承機制? 由於非 compile 範圍的依賴信息是不能在“依賴鏈”中傳遞的,所以有需要的工程只能單獨配置
- 創建父工程 創建父工程和創建一般的 Java 工程操作一致,唯一需要注意的是:打包方式處要設置為 pom
- 在子工程中引用父工程 ,從當前目錄到父項目的 pom.xml 文件的相對路徑
<code> <parent>
<groupid>com.starfish.maven/<groupid>
<artifactid>Parent/<artifactid>
<version>0.0.1-SNAPSHOT/<version>
<relativepath>../Parent/pom.xml/<relativepath>
/<parent>
/<code>
此時如果子工程的 groupId 和 version 如果和父工程重複則可以刪除。
- 在父工程中管理依賴 將 Parent 項目中的 dependencies 標籤,用 dependencyManagement 標籤括起來
<code><dependencymanagement>
<dependencies>
<dependency>
<groupid>junit/<groupid>
<artifactid>junit/<artifactid>
<version>4.9/<version>
<scope>test/<scope>
/<dependency>
/<dependencies>
/<dependencymanagement>
/<code>
在子項目中重新指定需要的依賴,刪除範圍和版本號
<code><dependency>
<groupid>junit/<groupid>
<artifactid>junit/<artifactid>
/<dependency>
/<code>
5.9. 聚合
- 為什麼要使用聚合?
將多個工程拆分為模塊後,需要手動逐個安裝到倉庫後依賴才能夠生效。修改源碼後也需要逐個手動進 行 clean 操作。而使用了聚合之後就可以批量進行 Maven 工程的安裝、清理工作。
如何配置聚合? 在總的聚合工程中使用 modules/module 標籤組合,指定模塊工程的相對路徑即可
<code>
<modules>
<module>starfish-learn-grpc/<module>
<module>starfish-learn-kafka/<module>
<module>starfish-web-demo/<module>
/<modules>
/<code>
鏈接:https://juejin.im/post/5e215a9ee51d453c951daa64
閱讀更多 追逐仰望星空 的文章