Maven的基本了解
什么是Maven阻肩?
Maven就是Apache下的一個開源項目。它是用純java開發(fā)的柒室。是一個項目管理工具雄右。使用Maven對java項目進行構(gòu)建、依賴管理逢渔。
項目構(gòu)建:
項目構(gòu)建包括代碼編寫肃廓、編譯铣鹏、測試吝沫、運行惨险、打包、部署和運行這幾個過程恭朗。傳統(tǒng)的項目構(gòu)建需要導入jar包來管理。對于Maven來說膀值,是通過pom.xml配置文件來配置所需要的依賴沧踏。
依賴管理:
一個java項目可能要使用一些第三方jar包才可以運行,那么我們的jar包依賴于第三方的jar包潦匈。所謂的依賴管理就是對項目所有依賴的jar包進行規(guī)范化管理茬缩。
Maven的好處
- Maven的項目體積小(體現(xiàn)在寡夹,jar包都不會保存在項目中魂角,而是通過pom配置文件查詢本地倉庫中的jar包)
- 可以一鍵構(gòu)建項目
注意:jar包雖然是保存在本地倉庫中野揪,但是并不會影響項目的打包
Maven的安裝和環(huán)境變量的配置
Maven下載地址:maven官網(wǎng)
直接解壓在本地中即可
1、MAVEN_HOME的配置
例如我的安裝目錄是:M:\SOFTWART\apache-maven-3.5.2
因為我方便移動迹恐,設置的是臨時變量挣惰。建議在用戶的全局變量中設置。
set path=M:\SOFTWART\apache-maven-3.5.2
2殴边、配置本地倉庫 - 也就是配置主鍵的存放位置憎茂,主鍵可以理解為依賴包
兩種方式:
- 用戶settings.xml配置文件中設置(用戶目錄/.m2中配置)
- 全局settings.xml配置文件中設置(Maven目錄/conf/setting.xml中配置)
建議采用第一種方式,好處是:第一種方式對其他用戶不影響锤岸,而且在Maven升級的時候需用修改用戶配置文件,而全局配置文件卻要修改是偷。
找到settings
根標簽拳氢,寫上關聯(lián)的本地倉庫位置
<localRepository>M:\DOCMENT\repository</localRepository>
Maven命令和生命周期
Maven的命令操作
clean:清理編譯的文件
compile:編譯主目錄代碼
test:編譯測試代碼,并運行代碼
package:打包(打包的文件名和類型取決于pom.xml)
install:就是把項目打包到本地倉庫目錄
tomcat:run: 一鍵啟動晓猛,Maven中tomcat默認版本是6饿幅,如果要使用其他版本(如:tomcat7:run)
Maven的生命周期
生命周期:為了對所有構(gòu)件過程進行抽象和統(tǒng)一凡辱。
這個生命周期包含了幾個過程:清理戒职、初始化、編譯透乾、測試洪燥、打包、集成測試乳乌、驗證捧韵、部署、站點生成
Maven擁有三套相互獨立的生命周期:clean生命周期汉操、default生命周期和site生命周期
clean生命周期
clean生命周期的目的是清理項目
包含三個階段:
-per-clean:執(zhí)行一些清理前需要完成的工作
- clean:清理上一次構(gòu)建生成的文件
- post-clean:執(zhí)行一些清理后需要完成的工作再来。
default生命周期
default生命周期的目的是構(gòu)建項目
核心階段:(略過其他的)
- process-source:處理項目主資源文件。對src/main/resources目錄的內(nèi)容進行變量替換等工作后,復制到項目輸出的主classpath目錄中芒篷。
- compile:編譯項目的主源碼搜变,編譯src/main/java目錄下的java文件至classpath目錄中。
- process-test-source:處理項目測試資源文件针炉。對src/test/resources目錄的內(nèi)容進行變量替換等工作后挠他,復制到項目輸出的主classpath目錄中。
- test-compile:編譯項目的測試代碼篡帕,編譯src/test/java目錄下的java文件至classpath目錄中殖侵。
- test:使用單元測試框架進行運行測試,測試代碼不會被打包或部署
- package:接收編譯好的代碼镰烧,打包成可發(fā)布的格式拢军,如jar
- install:將包安裝到Maven本地倉庫,供本地其他Maven項目使用
- deploy:將最終的包復制到遠程倉庫怔鳖,供其他開發(fā)人員和Maven項目使用
常見的打包方式:jar朴沿、war、pom败砂、maven-plugin赌渣、ear
site生命周期
site生命周期的目的是建立項目站點
- pre-site:執(zhí)行一些在生成項目站點之前需要完成的工作
- site:生成項目站點文檔
- post-site:執(zhí)行一些在生成項目站點之后需要完成的工作
- site-deploy:將生成的項目站點發(fā)布到服務器上。
不同的生命周期可以同時使用:
mvn clean install
mvn clean deploy site
mvn clean deploy site
命令的執(zhí)行階段:執(zhí)行clean生命周期的clean階段(包括per-clean昌犹、clean)坚芜、default生命周期的deploy階段(包含default生周期的全部階段)以及site生命周期的site-deploy階段(site生命周期的全部階段)
Maven倉庫
如果用過git的朋友應該知道,有本地的git倉庫斜姥,也有遠程的git倉庫鸿竖。對于Maven也是一樣的。
構(gòu)件
構(gòu)件:任何一個依賴铸敏、插件或者 項目構(gòu)建的輸出(項目打包后輸出的文件)都可以稱為構(gòu)件
任何一個構(gòu)件都有一組坐標唯一標識缚忧。
構(gòu)件在項目中的應用
了解Maven中處理倉庫布局的源碼,來了解Maven是如何通過坐標來表示倉庫的路徑
說明:
倉庫路勁為:log4j/log4j/1.2.15/log4j-1.2.15.jar (groupId/artifactId/version/artifactId-version.packageing)
坐標 =>
groupId=log4j
artifactId=log4j
version=1.2.15
packageing=jar
源碼解析:
private static final char PATH_SEPARATOR = '/';
private static final char GROUP_SEPARATOR = '.';
private static final char ARTIFACT_SEPARATOR = '-';
public String pathOf(Artifact artifact) {
ArtifactHandler artifactHandler = artifact.getArtifactHandler();
StringBuilder path = new StringBuilder(128);
path.append(formatAsDiretory(artifact.getGroupId())).append(PATH_SEPARATOR);
path.append(artifact.getArtifactId()).append(PATH_SEPARATOR);
path.append(artifact.getBaseVersion()).append(PATH_SEPARATOR);
path.append(artifact.getArtifactId()).append(ARTIFACT_SEPARATOR).append(artifact.getVersion());
if (artifact.hasClassifier()) {
path.append(ARTIFACT_SEPARATOR).append(artifact.getClassifier());
}
if (artifactHandler.getExtension() != null && artifactHandler.getExtension().length() >0 ) {
path.append(GROUP_SEPARATOR).append(artifactHandler.getExtension());
}
return path.toString();
}
private String formatAsDiretory (String directory) {
return directory.replace(GROUP_SEPARATOR, PATH_SEPARATOR);
}
=> artifact.getBaseVersion()主要是為SNAPSHOP版本服務的杈笔,例如version為1.0-SNAPSHOP的構(gòu)件闪水,其baseVersion就是1.0
=> classifier表示的是構(gòu)建輸出的一些附屬構(gòu)建,例如:javadoc蒙具、source
Maven倉庫種類
Maven倉庫分為三種:
- 本地倉庫(自己維護)
- 遠程倉庫
- 私服(公司維護)
- 中央倉庫(Maven團隊維護)
- 其他公共庫(其他人維護)
常見的遠程倉庫有:
JBoss Maven庫
添加中央倉庫鏡像 -- 阿里云鏡像
1球榆、在settings.xml中配置
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
2、在pom.xml中配置
<repositories>
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url
> <releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
updatePolicy表示用來配置Maven從遠程倉庫檢查更新的頻率禁筏,默認值是daily
- never:從不檢查更新
- always:每次構(gòu)建都檢查更新
- interval:X :每隔X分鐘檢查一次更新
- daily:每天檢查一次
checksumPolicy:用來配置Maven檢查檢驗和文件的策略持钉,當構(gòu)建部署到Maven倉庫的時候,會同時部署對應的校驗和文件篱昔。 - fail:Maven遇到檢驗和錯誤就讓構(gòu)建失敗
- ignore:使Maven完全忽略校驗和錯誤
私服
代表軟件:Nexus
使用私服的好處:
- 節(jié)省字節(jié)的外網(wǎng)帶寬
- 加速Maven構(gòu)建
- 部署第三方構(gòu)件
- 提高穩(wěn)定性每强,增強控制(不會受網(wǎng)絡的影響、權(quán)限管理、RELEASE和SNAPSHOT區(qū)分等)
- 降低中央倉庫的負荷
配置私服鏡像:
<mirror>
<id>mymaven</id>
<name>nexus respository</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
mirrorOf
-
*
:匹配所有遠程倉庫 -
external: *
:匹配所有遠程倉庫空执,使用localhost的除外窘茁,使用file://協(xié)議的除外。也就是說匹配所有不在本機上的遠程倉庫 -
repo1脆烟、repo2
:匹配倉庫repo1和repo2山林,使用, 來分割多個遠程倉庫 -
*,!repo1
:匹配所有的遠程倉庫邢羔,repo1除外
遠程倉庫的驗證以及部署配置
以私服來配置:
倉庫驗證
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
部署到遠程倉庫配置
<distributionManagement>
<repository>
<id>releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
distributionManagement包含repository和snapshotRepository
- repository:發(fā)布版本構(gòu)建的倉庫
- snapshotRepository:快照保本的倉庫
詳解pom.xml
了解版本 -- REALISE驼抹、SNAPSHOT
REALISE版本
REALISE版本是用來表示一個穩(wěn)定的版本
eg:1.0.0、1.3-alpha-4拜鹤、2.0
如果要更新到遠程倉庫里面框冀,需要更改版本號來更新最新的版本。獲取最新的版本也需要通過最新的版本號來標識
SNAPSHOT版本
SNAPSHOT版本是在標識一個不穩(wěn)定的版本敏簿∶饕玻可以用來指定開發(fā)過程中的一個版本的快照
eg:2.1-SNAPSHOT、2.1-20111211.221323-11(快照為2.1版本惯裕,與2011年12月11日22點12分23秒第11次修訂)
快照更新到遠程倉庫温数,在發(fā)布的過程中,Maven會自動為構(gòu)建打上時間戳蜻势。這樣在倉庫中就能找到該構(gòu)建2.1-SNAPSHOT的最新文件撑刺。
通常在配置文件中會設置Maven是多久檢查更新構(gòu)件,默認是一天檢查更新構(gòu)件是否為最新構(gòu)件握玛。在同一個版本的發(fā)布够傍,建議使用以下命令來更新版本
mvn clean install-U
了解坐標
Maven有個很大的優(yōu)勢就在于管理項目依賴。為了能自動地解析任何一個Java構(gòu)件挠铲,Maven就必須將它們唯一標識冕屯,這就是依賴管理的底層基礎 --- 坐標
坐標能夠快速、準確的定位到某個構(gòu)件(jar拂苹、war文件)安聘,通過設置中央倉庫的地址,可以快速的從該中央倉庫下載我們需要的一些主鍵醋寝。
坐標的詳解:(*表示必填)
-
groupId
*:定義該模塊隸屬于哪個公司的項目搞挣,表示方式和java包的表示方式類似带迟,與域名的定義方向一一對應音羞。 -
artifactId
*:定義該模塊的名稱。用于區(qū)分不同的功能模塊仓犬。 -
version
*:定義該模塊的版本定義 -
packaging
:定義該模塊的打包方式(jar嗅绰、pom、war),packaging是可選的窘面,默認為jar
翠语。 -
classifier
:該元素用來定義構(gòu)建輸出的一些附屬構(gòu)建。附屬構(gòu)建與主構(gòu)件對應财边。(例如主構(gòu)件的java文檔和源代碼 nexus-indexer-2.0.0-javadoc.jar肌括、nexus-indexer-2.0.0-sources.jar),不能直接定義酣难!
依賴標簽解析
根元素project下的dependencies可以包含一個或者多個dependency元素谍夭。
每個dependency元素包含的元素有:
-
groupId
*:(參考項目坐標) -
artifactId
*:(參考項目坐標) -
version
*:(參考項目坐標) -
type
:依賴的類型,對應于項目坐標定義的packaging憨募,一般來說都不必聲明默認是jar紧索, -
scope
:依賴的范圍 -
optional
:標記依賴是否可選 -
exclusions
:用來排除傳遞性依賴。
依賴范圍
包含以下5中菜谣,system一般在項目中很少用到
- compile:編譯依賴范圍(默認)珠漂,在編譯、測試和運行中都需要使用該依賴尾膊。代表主鍵:spring-core
- test:測試依賴范圍媳危,只在測試有效,編譯和運行時都無法使用該類依賴冈敛。代表主鍵:junit
- provided:已提供依賴范圍济舆,對在編譯和測試有效,在運行時無效莺债。代表主鍵:servlet-api
- runtime:運行時依賴范圍滋觉。對測試和運行有效,編譯無效齐邦。代表主鍵:mysql驅(qū)動包
- system:系統(tǒng)依賴范圍椎侠,和provided依賴范圍完全一致,此類依賴不是通過Maven倉庫解析措拇,依賴于操作系統(tǒng)的路徑我纪,所以移植性很差。必須通過systemPath元素來制定依賴文件的路徑丐吓,該元素也可以引用環(huán)境變量浅悉。
依賴范圍(Scope) | 對于編譯classpath有效 | 對于測試classpath有效 | 對于運行時classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驅(qū)動實現(xiàn) |
system | Y | Y | - | 本地類庫 |
依賴性和傳遞范圍
A依賴于B,B依賴于C券犁,則A對于B是第一直接依賴术健,B對于C是第二直接依賴。
第一直接依賴的范圍和第二直接依賴的范圍決定了傳遞性依賴的范圍
左邊是第一直接依賴粘衬,上邊為第二直接依賴荞估,中間的交叉單元格表示依賴傳遞的依賴范圍咳促。
compile | test | provided | runtime | |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
依賴優(yōu)先級原則
- 路徑最近者優(yōu)先:通過判斷依賴路徑的長度來優(yōu)先使用路徑較短的依賴
- 第一聲明者優(yōu)先:當依賴路徑相等時,在pom文件中聲明的順序決定了那個依賴優(yōu)先被解析使用勘伺。
各種依賴
可選依賴
A->B跪腹、B->X、B->Y
根據(jù)傳遞性依賴的定義飞醉,如果這三個依賴的范圍都是compile冲茸,那么X、Y就是A的compile范圍傳遞性依賴的定義缅帘。
然而噪裕,由于X、Y都是可選依賴股毫,依賴將不會得以傳遞膳音,即:X、Y將不會對A有任何影響
引入可選依賴特性可以解決X和Y的特性是互斥的情況铃诬,例如B是一個持久化層隔離工具包祭陷,依賴的X和Y是多種數(shù)據(jù)庫驅(qū)動包,我們在項目中使用該工具包的時候只會依賴于一種數(shù)據(jù)庫趣席。
optional元素標記依賴為可選依賴
如果B的兩個可選依賴為如下:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connection-java</artifactId>
<version>5.1.10</version>
<option>true</option>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc3</version>
<option>true</option>
</dependency>
</dependencies>
這兩個依賴只會對B產(chǎn)生影響兵志,當其他項目依賴于B的時候,這兩個依賴不會被傳遞宣肚。
當A依賴于B的時候想罕,可以顯示的聲明某個依賴
<dependencies>
<dependency>
<groupId>cn.lookzp.mvnbook</groupId>
<artifactId>B</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connection-java</artifactId>
<version>5.1.10</version>
</dependency>
</dependencies>
排除依賴
在dependency元素中使用exclusions
元素,exclusions中定義exclusion元素定義排除的依賴
<exclusions>
<exclusion>
<groupId>..</groupId>
<artifactId>...</artifactId>
</exclusion>
</exclusions>
歸類依賴
如果多個依賴中使用的版本是一樣的霉涨,或者方便管理依賴的版本按价,這時候可以使用歸類依賴來聲明依賴的版本信息。
在properties
中聲明版本變量屬性笙瑟,在properties中聲明的屬性名稱可以自定義楼镐。
在依賴中使用Maven的屬性,就需要使用 ${元素名稱} 的形式使用
<properties>
<springframework.version>2.5.6</springframework.version>
</properties>
優(yōu)化依賴
可以通過mvn dependency:list
或者mvn dependency:tree
命令查看到當前項目解析的依賴往枷。
mvn dependency:list
:羅列依賴
mvn dependency:tree
:以樹的形式羅列
Maven在Eclipse中的使用
Maven目錄結(jié)構(gòu)
|- src
|-main
|-java 主目錄代碼
|-resources 配置文件(property框产、xml)
|-webapp web文件夾(和webcontext是一樣的)
|-test
|-java 測試的java代碼
|-resources 測試的配置文件(不配置也行)
在eclipse中配置Maven
m2e軟件,一般在eclipse中已經(jīng)集成错洁,不需要自己安裝秉宿。如果eclipse沒有m2e插件,可以找到菜單項中的help
下的Install New Software...
屯碴,彈出框下的work with填寫http://download.eclipse.org/technology/m2e/releases
下載路徑描睦,然后然后下載插件即可
eclipse里面自帶里面的Maven版本可以用,但是一般配置自己Maven版本到項目中去
找到Installations和User Settings目錄窿锉,
Installations:選擇自己安裝的Maven軟件
User Settings:指向自己安裝的Maven項目的settings.xml配置文件酌摇,本地倉庫會自動定位到配置文件中的倉庫地址
Maven項目構(gòu)建
步驟:
1膝舅、 新建maven項目
2嗡载、 跳過骨架窑多,不跳過骨架創(chuàng)建的項目是目錄不全的
3、 填寫骨架
- group id:域名倒寫(如:cn.lookzp.hello)
- artifact id:開發(fā)模塊的項目名稱(如:HelloServelt)
- packaging:pom表示多人開發(fā)于一個項目洼滚,war表示的是web項目埂息,jar表示打包后可以給其他項目引用
- name:項目名稱(寫不寫意義不大)
- description:項目描述
4、 處理創(chuàng)建工程后的紅色叉號
一個web工程是需要web.xml配置文件的遥巴,但是跳過骨架創(chuàng)建的Maven工程師沒有web.xml文件的千康。
兩種解決方式:
- 拷貝其他項目中的web.xml文件
- 項目生產(chǎn)web.xml文件
-
配置動態(tài)web模塊的版本(默認是2.5版本),項目右鍵找到屬性
- 修改完后铲掐,需要更新一下maven拾弃,項目右鍵找到Maven -> Update Project
- 生成web.xml文件
很奇怪的是,每次生成web.xml都是修改Dynamic Web Module版本前的版本摆霉。所以我都是生成后刪除再刪除一邊豪椿。如果有已有的項目中存在,可以直接導入該web.xml配置文件
-
5携栋、 修改編譯的版本(參考下面的在pom.xml配置文件中常用的插件
小節(jié))搭盾,可以不配置
修改后必須 Maven -> Update Project
注:Dynamic Web Module的版本依賴于jdk的版本
6、 添加tomcat版本(參考下面的在pom.xml配置文件中常用的插件
小節(jié))婉支,可以不配置
修改后必須 Maven -> Update Project
7鸯隅、 運行項目:
項目右鍵 -> Run At -> Maven build...
-> Goals
如果已經(jīng)配置了的,以后運行直接找到Maven build
向挖,點擊運行即可
在pom.xml配置文件中常用的插件
處理編譯版本
默認的編譯版本為jdk1.5
<build>
<!-- 配置了很多插件 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
了解:可以在settings.xml中配置全局的jdk編譯版本
<profile>
<id>jdk18</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
添加tomcat插件
默認的tomcat為6蝌以,在控制面板中啟動tomcat6的執(zhí)行命令為mvn tomcat:run
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8000</port>
<path>/hello</path>
</configuration>
</plugin>
在控制面板中啟動tomcat7的執(zhí)行命令:mvn tomcat7:run
Maven索引中找到依賴
Window -> show View -> Other -> Maven -> Maven Repositories
在視圖中,右鍵Local Repository中添加索引
Maven中使用Debug模式
Debug模式的使用和tomcat的直接運行會有點不太一樣何之!
Debug模式需要選擇項目源來測試饼灿,在Source中,Add添加Project就能把項目加入到Debug調(diào)試模式中
Maven中快速添加junit測試
需要測試的類帝美,右鍵
選擇test目錄
分模塊開發(fā)Maven項目
在一個項目中碍彭,有可能存在多人開發(fā)的情況,這種情況就需要分工合作去開發(fā)悼潭,有可能一個Maven項目會分成幾個模塊進行開發(fā)庇忌,這樣每個模塊直接就需要銜接。這時候就需要依靠于私服來幫我們完成舰褪,將自己開發(fā)的模塊發(fā)布到私服中皆疹,給其他開發(fā)成員下載自己的模塊進行開發(fā)。
還記得前面講到的pom打包模式嗎占拍?這個就是運用于多人開發(fā)模式的
-
創(chuàng)建Maven父工程略就,選擇的packaging為:
pom
(多人開發(fā))
父工程中的pom.xml文件捎迫,所有的依賴和插件都在父工程的pom.xml中配的好處是,子工程都可以通過繼承的方式獲得依賴表牢,就不需要在子工程的pom.xml文件中進行配置
-
創(chuàng)建Maven子工程dao模塊窄绒,選擇的packaging為:
jar
,(這樣就可以依賴給其他項目)
dao模塊中的pom.xml配置
如果其他人需要依賴于你dao模塊中的信息崔兴,你需要把自己的模塊打包到私服中彰导,在項目中右鍵執(zhí)行命令install打包!然后再別人的項目中就可以通過依賴的方式把你的模塊打包到本地中進行開發(fā)敲茄。
以此類推
注:對于web模塊需要更改打包的方式為war