maven 公用仓库_Maven系列(二):Maven 核心概念
一、倉庫
1.1 Maven 倉庫
倉庫是一個位置(place),可以存儲所有的工程 jar 文件、library jar 文 件、插件或任何其他的工程指定的文件。
嚴格意義上說,Maven 只有兩種類型的倉庫:
- 本地(local)
- 遠程(remote)
1.2 本地倉庫
Maven 的本地倉庫是機器上的一個文件夾。它在你第一次運行任何 Maven 命令的時候創建。
Maven 的本地倉庫保存你的工程的所有依賴(library jar、plugin jar 等)。當你運行一次 Maven 構建時,Maven 會自動下載所有依賴的 jar 文件到本地倉庫中。它避免了每次構建時都引用存放在遠程倉庫上的依賴文件。
Maven 的本地倉庫默認被創建在 ${user.home}/.m2/repository目錄下。要修改默認位置,只要在 settings.xml 文件中定義另一個路徑即可,例如:
<localRepository>/anotherDirectory/.m2/respository
localRepository>
1.3 遠程倉庫
Maven 的遠程倉庫可以是任何其他類型的存儲庫,可通過各種協議,例如 file://和 http://來訪問。
這些存儲庫可以是由第三方提供的可供下載的遠程倉庫,也可以是在公司內的 FTP 服務器或 HTTP 服務器上設置的內部存儲庫,用于在開發團隊和發布之間共享私有的 artifacts。
中央倉庫
Maven 的中央倉庫是 Maven 社區維護的,里面包含了大量常用的庫,我們可以直接引用,是一個遠程公用倉庫,URL 地址:http://search.maven.org/[1]
第三方倉庫
也叫私服,是指公司自己內部搭建的公共類庫站點,只提供給公司內部共享服務所使用,通常都是搭建在局域網內部使用,而且對于內部私服的連接,通常公司都會有相關的賬號密碼進行控制。
1.4 倉庫之間的關系
前面介紹了三種倉庫,那這些倉庫之間的關系是怎樣的呢?或者說一個 Maven 項目想要獲取一個jar包的話,他該從哪個倉庫中去獲取呢?
但是這中間只要在某一個倉庫中找到了就會返回了,除非倉庫中有更新的版本,或者是snapshot版本。
1.5 倉庫配置
假設我們要配置一個中央倉庫,可以像下面這樣配置:
<project><profiles>
<profile>
<id>centralid>
<repositories>
<repository>
<id>Centralid>
<name>Centralname>
<url>http://repo.maven.apache.org/maven2/url>
repository>
repositories>
profile>
profiles>
<activeProfiles>
<activeProfile>centralactiveProfile>
activeProfiles>
...
project>
1.6 倉庫管理器
如果每個開發者都單獨配置一個中央倉庫,那每個人都到中央倉庫中去下載所需的 jar,這就退化成最原始的模式,并且是一個巨大的資源浪費。
倉庫管理器是一種專用服務器應用程序,目的是用來管理二進制組件的存儲庫。對于任何使用 Maven 的項目,倉庫管理器的使用被認為是必不可少的最佳實踐。
倉庫管理器提供了以下基本用途:
使用倉庫管理器可以獲得以下優點和功能:
二、鏡像
鏡像(Mirror) 相當于一個代理,它會攔截去指定的遠程倉庫下載構件的請求,然后從自己這里找出構件回送給客戶端。配置鏡像的目的一般是出于網速考慮。
倉庫和鏡像是兩個不同的概念:前者本身是一個倉庫,可以對外提供服務,而后者本身并不是一個倉庫,它只是遠程倉庫的網絡加速器。
如果倉庫X 可以提供 倉庫Y 存儲的所有內容,那么就可以認為 X是Y的一個鏡像。這也意味著,任何一個可以從某個倉庫中獲得的構件,都可以從它的鏡像中獲取。
舉個例子:http://maven.net.cn/content/groups/public/[2] 是中央倉庫 http://repo1.maven.org/maven2/[3] 在中國的鏡像,由于地理位置的因素,該鏡像往往能夠提供比中央倉庫更快的服務。
因此,可以在 Maven 中配置該鏡像來替代中央倉庫。在settings.xml中配置如下代碼:
<settings>...
<mirrors>
<mirror>
<id>maven.net.cnid>
<mirrorOf>centralmirrorOf>
<name>one of the central mirrors in chinaname>
<url>http://maven.net.cn/content/groups/public/url>
mirror>
mirrors>
...
settings>
對于鏡像的最佳實踐是結合私服。由于私服可以代理任何外部的公共倉庫(包括中央倉庫),因此,對于組織內部的 Maven用戶來說,使用一個私服地址就等于使用了所有需要的外部倉庫,這可以將配置集中到私服,從而簡化 Maven 本身的配置。在這種情況下,任何需要的構件都可以從私服獲得,私服就是所有倉庫的鏡像。
三、Maven 坐標
3.1 pom.xml
Project Object Model:項目對象模型。它是 Maven 的核心配置文件,所有的構建的配置都在這里設置。
3.2 Maven 坐標
使用groupId、artifactId、version 三個向量在倉庫中唯一的定位一個 Maven 工程。
- groupId:組織標識(包名)
- artifactId:項目名稱
- version:項目的當前版本
示例:
3.3 Maven 為什么使用坐標?
- Maven 世界擁有大量構建,我們需要找一個用來唯一標識一個構建的統一規范;
- 擁有了統一規范,就可以把查找工作交給機器。
四、依賴管理
Maven 核心特點之一是依賴管理。一旦我們開始處理多模塊工程(包含數百個子模塊或者子工程)的時候,模塊間的依賴關系就變得非常復雜,管理也變得很困難。針對此種情形,Maven 提供了一種高度控制的方法。
4.1 依賴配置
依賴配置主要包含如下元素:
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.9version>
<scope>testscope>
dependency>
<dependency>
<groupId>cn.vangroupId>
<artifactId>mavenartifactId>
<version>0.0.1-SNAPSHOTversion>
<scope>compilescope>
dependency>
dependencies>
Maven 解析依賴信息時會到本地倉庫中取查找被依賴的 jar 包;
如果依賴的是自己或者團隊開發的 Maven 工程,需要先使用 install 命令把被依賴的 Maven 工程的 jar 包導入到本地倉庫中
舉例:現在我再創建第二個 Maven 工程 hello-word,其中用到了第一個 maven-demo 工程里類的 sayHello(String name) 方法,我們在給 hello-word 項目使用 mvn compile 命令進行編譯的時候,會提示缺少依賴 maven-demo 的 jar 包。怎么辦呢?
到第一個 Maven 工程中執行 mvn?install 后,你再去看一下本地倉庫,你會發現有了 maven-demo 項目的 jar 包,一旦本地倉庫有了maven-demo 工程的 jar 包后,你再到 hello-word 項目中使用 mvn compile 命令的時候,可以成功編譯
4.2 依賴范圍
依賴范圍 scope 用來控制依賴和編譯,測試,運行的 classpath 的關系. 主要的是三種依賴關系如下: 1.compile:默認編譯依賴范圍。適用于所有階段(開發、測試、部署、運行),本jar會一直存在所有階段;1.provided:只在開發、測試階段使用,但對于運行無效;1.runtime: 只在運行時使用。例如: jdbc 驅動;1.test:只在測試時使用,用于編譯和運行測試代碼。不會隨項目發布。
4.3 傳遞性依賴
Apple.jar 直接依賴于 Vegetables.jar,而 Vegetables.jar 又直接依賴于 Food.jar,那么 Apple.jar 也依賴于 Food.jar,這就是傳遞性依賴,只不過這種依賴是間接依賴,如下圖所示:
4.4 依賴沖突
當同一個項目中由于不同的jar包依賴了相同的jar包,此時就會發生依賴沖突的情況,如圖所示:
當項目中依賴了a和c,而a和c都依賴了b,這時就造成了沖突。為了避免沖突的產生,Maven 使用了兩種策略來解決沖突,分別是路徑最短者優先原則和路徑相同先聲明優先原則 。
- 路徑最短者優先原則
從項目一直到最終依賴的jar的距離,哪個距離短就依賴哪個,距離長的將被忽略掉。
- 路徑相同先聲明優先原則
通過jar包聲明的順序來決定使用哪個,最先聲明的jar包總是被選中,后聲明的jar包則會被忽略。
4.5 依賴排除
如果我們只想引用我們直接依賴的jar包,而不想把間接依賴的jar包也引入的話,那可以使用依賴排除的方式,將間接引用的jar包排除掉。
<exclusions><exclusion>
<groupId>excluded.groupIdgroupId>
<artifactId>excluded-artifactIdartifactId>
exclusion>
exclusions>
4.6 聚合
<modules><module>模塊一module>
<module>模塊二module>
<module>模塊三module>
modules>
將多個項目同時運行就稱為聚合,如下就是 apple、orange、peal 這三個模塊聚合。
<modules><module>applemodule>
<module>orangemodule>
<module>pealmodule>
modules>
聚合的優勢在于可以在一個地方編譯多個 pom.xml 文件。
聚合時 packaging 必須要是 pom
4.7 繼承
繼承為了消除重復,我們把很多相同的配置提取出來。
- 繼承配置代碼(父pom中的依賴)
maven-parent
1.0.0-SNAPSHOT
junitjunit${junit.version}test
- 繼承代碼中定義屬性(在子 pom 中引入這個父 pom)
cn.vanmaven-parent1.0.0-SNAPSHOT
junitjunit
- 用 dependencyManagement ,可對依賴進行管理
這樣的好處是子模塊可以有選擇行的繼承,而不需要全部繼承。
子類只要不引用這個里面寫的groupId + artifactId,則不會添加依賴。
- 聚合與繼承的關系
聚合主要為了快速構建項目,繼承主要為了消除重復
五、生命周期
Maven 生命周期就是為了對所有的構建過程進行抽象和統一,包括項目清理,初始化,編譯,打包,測試,部署等幾乎所有構建步驟。
5.1 Maven 三大生命周期
Maven 有三套相互獨立的生命周期,請注意這里說的是 三套,而且 相互獨立,這三套生命周期分別是:
再次強調一下它們是相互獨立的,你可以僅僅調用 clean 來清理工作目錄,僅僅調用 site 來生成站點。當然你也可以直接運行 mvn clean install site 運行所有這三套生命周期。
5.2 Clean Lifecycle 生命周期
每套生命周期都由一組階段 (`Phase`) 組成,我們平時在命令行輸入的命令總會對應于一個特定的階段。`Clean Lifecycle` 生命周期一共包含了三個階段:1. `pre-clean`:執行一些需要在 `clean` 之前完成的工作;
2. `clean`:移除所有上一次構建生成的文件;
3. `post-clean`:執行一些需要在 `clean` 之后立刻完成的工作。
mvn clean 中的 clean 就是上面的 clean,在一個生命周期中,運行某個階段的時候,它之前的所有階段都會被運行,也就是說,mvn clean 等同于 mvn pre-clean clean ,如果我們運行 mvn post-clean ,那么 pre-clean,clean 都會被運行。這是 Maven 很重要的一個規則,可以大大簡化命令行的輸入。
5.3 Default Lifecycle 生命周期
`Default Lifecycle` 生命周期是 `Maven` 生命周期中最重要的一個,絕大部分工作都發生在這個生命周期中:編譯,測試,打包,部署等等。這里,只解釋一些比較重要和常用的階段:* `validate`
* `generate-sources`
* `process-sources`
* `generate-resources`
* `process-resources`:復制并處理資源文件,至目標目錄,準備打包。
* `compile`:編譯項目的源代碼。
* `process-classes`
* `generate-test-sources`
* `process-test-sources`
* `generate-test-resources`
* `process-test-resources`:復制并處理資源文件,至目標測試目錄。
* `test-compile`:編譯測試源代碼。
* `process-test-classes`
* `test`:使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
* `prepare-package`
* `package`:接受編譯好的代碼,打包成可發布的格式,如 JAR 。
* `pre-integration-test`
* `integration-test`
* `post-integration-test`
* `verify`
* `install`:將包安裝至本地倉庫,以讓其它項目依賴。
* `deploy`:將最終的包復制到遠程的倉庫,以讓其它開發人員與項目共享。
運行任何一個階段的時候,它前面的所有階段都會被運行,這也就是為什么我們運行 mvn install 的時候,代碼會被編譯,測試,打包。此外,Maven 的插件機制是完全依賴 Maven 的生命周期的,因此理解生命周期至關重要。
5.4 Site Lifecycle 生命周期
該周期生成項目報告,站點,發布站點。1. `pre-site` 執行一些需要在生成站點文檔之前完成的工作;
1. `site`:生成項目的站點文檔;
1. `post-site`:執行一些需要在生成站點文檔之后完成的工作,并且為部署做準備;
1. `site-deploy`:將生成的站點文檔部署到特定的服務器上。
這里經常用到的是 site 階段和 site-deploy 階段,用以生成和發布 Maven 站點,這是 Maven 相當強大的功能。
六 Maven 插件
插件是 Maven 的核心,所有執行的操作都是基于插件來完成的。
為了讓一個插件中可以實現眾多的相類似的功能,Maven 為插件設定了目標,一個插件中有可能有多個目標。其實生命周期中的每個階段都是由插件的一個具體目標來執行的。
Maven 的生命周期與插件目標相互綁定,以完成某個具體的構建任務,比如通過 mybatis-generator 我們可以生成很多DAO層的代碼。
七、指令
7.1 構建 Maven 項目
Maven作為一個高度自動化構建工具,本身提供了構建項目的功能,下面就來體驗一下使用 Maven 構建項目的過程。
- Maven 項目的目錄約定
|----src
| |----main
| | |----java ——存放項目的. java 文件
| | |----resources ——存放項目資源文件,如 spring, mybatis 配置文件
| |----test
| | |----java ——存放所有測試. java 文件,如 JUnit 測試類
| | |----resources ——存放項目資源文件,如 spring, mybatis 配置文件
|----target ——項目輸出位置
|----pom.xml ---- 用于標識該項目是一個 Maven 項目
- 使用mvn archetype:generate命令
mvn archetype:generate -DgroupId=cn.van -DartifactId=maven-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- 使用mvn archetype:create命令
mvn archetype:create -DgroupId=cn.van -DartifactId=maven-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
使用mvn archetype:generate命令和mvn archetype:create都可以創建項目,區別就是使用使用mvn archetype:create命令創建項目更快。
- Maven 創建項目的命令說明
mvn archetype:create或者mvn archetype:generate是固定寫法
-DgroupId 組織標識(包名)-DartifactId 項目名稱
-DarchetypeArtifactId 指定ArchetypeId:maven-archetype-quickstart,創建一個Java Project;maven-archetype-webapp,創建一個Web Project
-DinteractiveMode 是否使用交互模式
1. archetype是mvn內置的一個插件;1. create任務可以創建一個java項目骨架;1. DgroupId是軟件包的名稱;1. DartifactId是項目名;1. DarchetypeArtifactId是可用的mvn項目骨架,目前可以使用的骨架有:
- maven-archetype-archetype
- maven-archetype-j2ee-simple
- maven-archetype-mojo
- maven-archetype-portlet
- maven-archetype-profiles (currently under development)
- maven-archetype-quickstart
- maven-archetype-simple (currently under development)
- maven-archetype-site
- maven-archetype-site-simple
- maven-archetype-webapp
每一個骨架都會建相應的目錄結構和一些通用文件,最常用的是maven-archetype-quickstart(創建一個Java Project)和maven-archetype-webapp(創建一個JavaWeb Project)骨架。
7.2 使用 Maven 編譯項目
在項目創建完成后,一般來說,接著我們就可以將創建好的項目導入IDEA/Eclipse中進行開發了,我們這里直接跳過,直接假設開發完成,進行編譯/打包等流程。
編譯項目的命令是:mvn compile
* 進入項目根目錄執行mvn compile 命令編譯項目;
* 編譯成功之后,可以看到項目的根目錄下多了一個target文件夾,這個文件夾就是編譯成功之后 Maven 幫我們生成的文件夾;
* 打開target文件夾,可以看到里面有一個classes文件夾,classes文件夾中存放的就是 Maven 我們編譯好的字節碼文件。
這就是使用 Maven 自動編譯項目的過程。編譯完成,你需要的的依賴的包已經自動導入到本地倉庫了。
7.3 使用 Maven 清理項目
清理項目的命令是:mvn clean
進入項目根目錄執行mvn clean命令清理項目,清理項目的過程就是把執行mvn compile命令編譯項目時生成的 target 文件夾刪掉。
7.4 使用 Maven 測試項目
測試項目的命令是:mvn test
* 進入項目根目錄執行 mvn test 命令測試項目;
* 測試成功之后,可以看到項目的根目錄下多了一個target文件夾,這個文件夾就是測試成功之后 Maven 幫我們生成的文件夾;
* 打開target文件夾,可以看到里面有一個classes和test-classes文件夾,如下圖所示:
也就是說,我們執行執行 mvn test命令測試項目時,Maven 先幫我們編譯項目,然后再執行測試代碼。
7.5 使用 Maven 打包項目
打包項目的命令是:mvn package
進入項目根目錄執行 mvn package 命令測試項目;
打包成功之后,可以看到項目的根目錄下的target文件夾中多了一個 maven-demo-1.0-SNAPSHOT.jar,這個 maven-demo-1.0-SNAPSHOT.jar 就是打包成功之后 Maven 幫我們生成的 jar 文件,如下圖所示:
7.6 使用 Maven 安裝項目
安裝項目的命令是:mvn install
進入項目根目錄執行 mvn install 命令測試項目;
安裝成功之后,首先會在項目的根目錄下生成target文件夾,打開target文件夾,可以看到里面會有 maven-demo-1.0-SNAPSHOT.jar,這個 maven-demo-1.0-SNAPSHOT.jar 就是安裝成功之后 Maven 幫我們生成的 jar 文件,如下圖所示:
除此之外,在我們存放 Maven 下載下來的 jar 包的倉庫也會有一個 maven-demo-1.0-SNAPSHOT.jar,所以 Maven 安裝項目的過程,實際上就是把項目進行【清理】→【編譯】→【測試】→【打包】,再把打包好的 jar 放到我們指定的存放 jar 包的 Maven 倉庫中
所以使用 mvn install 命令,就把 Maven 構建項目的 【清理】→【編譯】→【測試】→【打包】 的這幾個過程都做了,同時將打包好的 jar 包發布到本地的 Maven 倉庫中,所以 Maven 最常用的命令還是 mvn install,這個命令能夠做的事情最多。
文中鏈接
[1]http://search.maven.org/
[2]http://maven.net.cn/content/groups/public/
[3]http://repo1.maven.org/maven2/
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的maven 公用仓库_Maven系列(二):Maven 核心概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: myeclipse 项目右键没有svn_
- 下一篇: bt5重启网卡命令_BackTrack