先上學習圖譜!
Maven概覽
- 爲什麼使用Maven?
目前問題:
1. jar包混亂:工程中存在jar包重複,版本不一致的情況.
2. 添加jar包隨意:需要用到第三方jar時,隨便下載就添加到項目中了,沒有記錄
3. 重複構建:每個開發人員從svn下載完代碼後,都要對項目進行配置,構建.
4. 不同環境的構建差異:總是存在在開發環境運行良好的程序,到了測試環境編譯不通過,或者不同環境的配置文件不一致,需要手動的去修改
5. 模塊間的開發依賴純手動處理:提倡模塊化的開發,可是怎麼做好模塊化開發之間的依賴處理,沒有解決方案。
- Maven介紹
maven是什麼?
Maven是一個項目管理和綜合工具。Maven提供了開發人員構建一個完整的生命週期框架。開發團隊可以自動完成項目的基礎工具建設,Maven使用標準的目錄結構和默認構建生命週期。
在多個開發團隊環境時,Maven可以設置按標準在非常短的時間裏完成配置工作。由於大部分項目的設置都很簡單,並且可重複使用,Maven讓開發人員的工作更輕鬆,同時創建報表,檢查,構建和測試自動化設置。
Maven能幹什麼?
- 項目構建
- 依賴管理
- 倉庫管理
- web項目與自動化部署
- 聚合和繼承。。等
maven的優點:
- 對第三方依賴庫進行統一的版本管理。
- 統一項目的目錄結構。
- 統一軟件構建階段
- 支持多種插件
- 自動生成項目網站和報表
- Maven下載
官網地址:http://maven.apache.org/
目錄結構:
-
bin:maven的運行腳本,mvn.cmd是基於Windows的腳本。在CMD中每次輸入一條MVN的命令都是在調用並執行這些腳本。
-
boot:該目錄只有一個文件plexus-classworlds-2.5.2.jar。它是一個類加載器的框架,相對於JDK中的類加載器,它提供了更豐富的語法以方便配置,maven使用該框架加載自己的類庫。
-
conf:該目錄包含了一個非常重要的文件settings.xml。配置該文件就能在Project中定製maven的行爲。
-
lib:包含了所有的maven運行需要的java類庫以及用到的第三方類庫。
- Maven環境變量配置
1. 下載apache-maven-3.5.0-bin.zip
2. 配置maven的環境變量
3. 執行mvn命令驗證:mvn -v
注:Maven 3.3+ require JDK 1.7 or above to execute
Maven常用命令
創建java工程
mvn archetype:generate
-DgroupId 公司名
-DartifactId 項目名稱
-DgroupId 公司名
-DarchetypeArtifactId 骨架
(指定ArchetypeId,maven-archetype-quickstart是java工程,maven-archetype-webapp是web工程)
-DinteractiveMode 是否使用交互模式
關於pom.xml
maven工程結構和內容定義在pom.xml中,全稱即爲project object moduel
約定優於配置
maven使用約定而不是配置,意味着開發者不需要再自己創建構建過程。
當創建maven工程時,maven會創建默認的工程結構,開發者只需要合理的放置配置文件,而在pom.xml中無需做任何配置。
src
-main
–bin 腳本庫
–java java源代碼文件
–resources 資源庫,會自動複製到classes目錄裏
–filters 資源過濾文件
–assembly 組件的描述配置(如何打包)
–config 配置文件
–webapp web應用的目錄。WEB-INF、css、js等
-test
–java 單元測試java源代碼文件
–resources 測試需要用的資源庫
–filters 測試資源過濾庫
-site Site(一些文檔)
target 存放當前編譯後的源文件
LICENSE.txt Project’s license
README.txt Project’s readme
mvn compile 編譯源代碼
mvn clean 清空target
mvn package 打包
mvn install 安裝輸出文件到本地倉庫
mvn clean package 先清除再打包
mvn jar:jar 打成jar包
mvn deploy 發佈到遠程倉庫
mvn dependency:tree > d.txt maven依賴結構
mvn site
- Maven座標
maven座標-maven構件
什麼是maven構件?
在maven中,任何依賴(jar包),或者項目輸出(自己打包的jar、war等)都可以成爲構件。
每個構件都有自己的唯一標識(唯一座標),由groupId,artifactId,version等信息構成。
- groupId:一般代表公司名,或者組織名
- artifactId:一般項目名稱
- version:當前項目的版本號
- packaging:定義maven項目打包的方式,也可以打包成war等,當不定義packaging時,maven會默認值jar
- Maven倉庫
maven在某個統一的位置存儲所有項目的共享的構件,這個統一的位置,我們就稱之爲倉庫。(倉庫就是存放依賴和構件的地方)
maven的分類:
1. 本地倉庫
2. 遠程倉庫
在遠程倉庫中分成3類:
- 中央倉庫
- 私服
- 其他公共庫。
1.本地倉庫,顧名思義,就是Maven在本地存儲構件的地方。注:maven的本地倉庫,在安裝maven後並不會創建,它是在第一次執行maven命令的時候才被創建
maven本地倉庫的默認位置:無論是Windows還是Linux,在用戶的目錄下都有一個.m2/repository的倉庫目錄,這就是maven倉庫的默認位置。
如何更改maven默認的本地倉庫的位置,需要修改setttings.xml文件中localRepository標籤
用戶範圍修改 把settings.xml放到.m2文件下
全局修改 maven目錄conf中settings.xml
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
- Maven生命週期
maven有三套相互獨立的生命週期,一般的容易將maven的生命週期看成一個整體,其實不然,這三套生命週期分別是:
Clean Lifecycle 在進行真正的構建之前進行一些清理工作
Default Lifecycle 構建的核心部分,編譯、測試、打包、部署等。
Site Lifecycle 生成項目報告,站點,發佈站點。
每套生命週期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應於一個特定的階段。比如,運行mvn clean ,這個的clean是Clean生命週期的一個階段。
運行任何一個階段的時候,它前面的所有階段都會被運行,這也就是爲什麼我們運行mvn install的時候,代碼會被編譯,測試,打包。
一、maven的生命週期
maven的生命週期就是對所有的構建過程進行抽象和統一。包含了項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎所有的構建步驟。
二、3套生命週期
maven有三套獨立的生命週期,分別是clean,default,site。每個生命週期包含一些階段(phase),階段是有順序的,後面的階段依賴前面的階段。
- clean生命週期:清理項目,包含三個phase
(1.1)pre-clean:執行清理前需要完成的工作
(1.2)clean:清理上一次構建生成的文件
(1.3)post-clean:執行清理後需要完成的工作。
- default生命週期:構建項目,重要的phase:
(2.1)validate:驗證工程是否正確,所有需要的資源是否可用
(2.2)compile:編譯項目的源代碼
(2.3)test:使用合適的單元測試框架來測試已編譯的源代碼,這些測試不需要已打包和部署。
(2.4)package:把已編譯的代碼打包成可發佈的格式,比如jar。
(2.5)install:把包安裝到maven本地倉庫,可以被其他工程作爲依賴來使用
(2.6)deploy:在集成或者發佈環境下執行,將最終版本的包拷貝到遠程的repository,使得其他的開發者或者工程可以共享。
3. site生命週期:建立和發佈項目站點
(3.1)pre-site:生成項目站點之前需要完成的工作
(3.2)site:生成項目站點文檔
(3.3)post-site:生成項目站點之後需要完成的工作
(3.4)site-deploy:將項目站點發布到服務器
三、命令行和生命週期
各個生命週期相互獨立,一個生命週期的階段前後依賴。
- pom.xml詳解
parent 集成,父模板的座標
distributionManagement 負責管理構件發佈配置
version 定義規則:
snapshot 快照
alpha 內側
beta 公測
release 穩定版本
GA 最穩定版本
。。。
maven會根據模塊的版本號(pom文件中的version)中是否帶有-SNAPSHOT來判斷是快照版本還是正式版本。
快照能被覆蓋,正式版不能被覆蓋(當然倉庫配置爲redeploy是能被覆蓋的,比較坑)。
定義版本規則的:
<主版本>.<次版本>.<增量版本>
比如說1.2.3,主版本是1,次版本是2,增量版本是3。
module 聚合和哪些模塊
dependencies 依賴集合
dependencyManagement 用於定義共同的依賴jar包,用戶其他項目集成時使用同一的版本jar包,子模塊不需要指定版本號
name url 是生成站點信息時用到
properties 屬性標籤,是在maven編譯的時候發揮作用,例如:UTF-8 默認編碼爲UTF-8
還可以指定一些數據庫的連接信息
還可以自定義標籤統一管理我的所有的jar版本號,${取值}
build 裏面放的是插件
plugins 插件
intellij maven插件
maven配置
打開 -> File -> Settings -> Maven
Maven home dictionary:
User Settings file:
Local repository:
Maven特性
- 依賴
maven的依賴範圍就是用來控制與編譯、測試、運行三種classpath的關係。
maven有以下幾種依賴範圍:
1. compile的範圍(默認)
當依賴的scope爲compile的時候,那麼當前這個依賴的包,會在編譯的時候將這個依賴加入進來,並且在打包(mvn package)的時候也會將這個依賴加入進去。
意思就是:編譯範圍有效,在編譯打包時都會存儲進去
2. provided的範圍
當依賴的scope爲provided的時候,在編譯測試有效,在執行(mvn package)進行打包成war包時不會加入,比如:servlet-api,因爲servlet-api在tomca等容器中已經存在,如果在打包進去的話,那麼包之間會衝突。
3. test的範圍
當依賴的scope爲test時,指的是在測試範圍有效,在編譯與打包的時候不會使用這個依賴。
4. runtime的範圍
當依賴的scope爲runtime的時候,在運行的時候纔會有依賴,在編譯的時候不會依賴
5. system(系統範圍)
system範圍依賴於provided類似,但是你必須顯示的提供一個對於本地系統中JAR文件的路徑,這麼做是爲了允許基於本地對象編譯,而這些對象是系統類庫的一部分,這樣的構建應該是一直可用的,maven也不會在倉庫中去尋找它,如果你將一個依賴範圍設置成系統範圍,你必須同時提供一個systemPath元素,注意該範圍是不推薦使用的(你應該一直儘量去公共或者定製的maven倉庫中引用依賴)
注:默認情況下的scope範圍是compile
- 傳遞性
我們的依賴是有傳遞性的。
規則:
-
路徑最近者優先,c->b->a
c依賴b,b依賴a,c會優先使用b的jar包
-
路徑相同配置最前者優先,c->b, c->a
c依賴b,c依賴a,必須要看b、a在c中哪個先聲明的,優先使用先聲明的jar包。
傳遞依賴會產生一個問題,是什麼?
如何解決這個問題?
在這裏提一下gradle依賴,會依賴最新版本的jar。
如果在傳遞依賴的包中,想去除某個jar包
原因:
- 降低工程的依賴數量
- 解決jar包版本衝突(ClassNotFound)
問題:如何查找衝突的jar包?
選擇性依賴
在依賴中用jar直接去除這種依賴傳遞的特性,也就是說,如果別的項目引用設置了此依賴的項目,這個commons-logging不會被依賴到,例如在項目A中配置commons-logging的依賴,如果項目B依賴項目A,則在B中不會依賴commons-logging了。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
排除依賴
如果第三方的jar包沒有用去除依賴的傳遞性,那麼我們可以在當前的項目中使用元素聲明排除依賴。
例如:項目A中配置了spring-core的依賴,如果項目B需要引用項目A,但是同時又不需要commons-logging的包,這個時候可以使用
元素排除即可,這種用法可以解決包版本衝突的問題。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
小技巧:pom.xml 右擊->Diagrams
- 聚合
一個項目往往由多個模塊構成的,在進行構建時,針對每個模塊都進行構建命令是一件非常繁瑣又容易出錯的事情,所以maven的聚合功能能夠替我們完成進行一次構建命令完成全部模塊的的構建。
maven的聚合功能可以通過一個父模塊講所有的要構建模塊整合起來,將父模塊的打包類型聲明爲POM,通過將各模塊集中到父pom中。
<modules>
<module>test-service</module>
<module>test-facade</module>
<module>test-dao</module>
</modules>
- 繼承
maven中繼承的概念與面向對象的繼承概念是一致的,通過繼承消除重複編碼的行爲。在這裏,我們也可以通過一個父模塊來挖財父模塊與子模塊共用依賴的繼承關係。父模塊的POM文件聲明與平常一樣,提取公共地方,子模塊需要繼承父模塊。
注:通過parent標籤進行繼承
另外:
-
子模塊沒有聲明groupId和version,這兩個屬性繼承至父模塊。但如果子模塊有不同與父模塊的groupId、version,也可以指定。
-
不應該繼承artifactId,如果groupId,version,artifactId完全繼承的話會造成座標衝突;另外即使使用不同的groupId或version,同樣的artifactId也容易產生混淆。
-
使用繼承後parent也必須像子模塊一樣加入到聚合模塊中。
maven可繼承的POM元素
groupId: 項目組ID,項目座標的核心元素
version:項目版本
description:項目的描述信息
organization:項目的組織信息
inceptionYear: 項目的創建年份
url: 項目的url地址
develovers: 項目開發者信息
distributionManagement:項目的部署信息
properties:自定義的maven屬性
build:組件
。。。。
福利小彩蛋
精心整理380頁Maven文檔助你成就完成高薪夢!
由於平臺文章篇幅限制,細節內容過多,所以只把部分知識點截圖出來粗略的介紹,每個小節點裏面都有更細化的內容!,需要獲取Maven實戰核心知識點的pdf文檔的可以關注我的公衆號【風平浪靜如碼】回覆關鍵字【Maven】免費領取!
1,2,3章Maven簡介與安裝和配置講解,及使用入門
4,5,6章Maven背景案例、座標和依賴及倉庫講解
7,8章生命週期和插件及集合與繼承講解
9章使用Nexus創建私服
10,11章maven進行測試及使用Hudson進行持續集成講解
12,13章使用Maven架構Web應用及版本管理講解
14,15章靈活的架構及生成項目站點講解
16章m2eclipse講解
17,18章編寫Maven插件及Archetype講解
由於平臺文章篇幅限制,細節內容過多,所以只把部分知識點截圖出來粗略的介紹,每個小節點裏面都有更細化的內容!,需要獲取Maven實戰核心知識點的pdf文檔的可以關注我的公衆號【風平浪靜如碼】回覆關鍵字【Maven】免費領取!