Maven到底是個啥?——Maven深入理解

一、maven

1.maven簡介

  • Apache Maven是一個軟件項目管理和綜合工具。基於項目對象模型(POM)的概念,Maven可以從一箇中心資料片管理項目構建,報告和文件。

  • 簡單理解爲統一管理jar包的倉庫。

  • maven項目採用“約定優於配置”的原則,src/main/java約定用於存放源代碼,src/main/test用於存放單元測試代碼,src/target用於存放編譯、打包後的輸出文件。

2.Maven版本管理

  • maven中的倉庫分爲兩種,snapshot快照倉庫和release發佈倉庫。snapshot快照倉庫用於保存開發過程中的不穩定版本,release正式倉庫則是用來保存穩定的發行版本。
  • 如果是快照版本,那麼在mvn deploy時會自動發佈到快照版本庫中,會覆蓋老的快照版本,而在使用快照版本的模塊,在不更改版本號的情況下,直接編譯打包時,maven會自動從鏡像服務器上下載最新的快照版本。
  • 如果是正式發佈版本,那麼在mvn deploy時會自動發佈到正式版本庫中,而使用正式版本的模塊,在不更改版本號的情況下,編譯打包時如果本地已經存在該版本的模塊則不會主動去鏡像服務器上下載。

3.Maven生命週期

生命週期(lifecycle)可以理解成由各種plugin按照一定的順序執行來完成java項目清理、編譯、打包、測試、佈署等整個項目的流程的一個過程。各個插件的執行順序一般是:1.clean、2.resources、3.compile、4.testResources、5.testCompile、6.test、7.jar、8.install。

  • clean階段是獨立的一個階段,功能就是清除工程目前下的target目錄,對應的插件是 maven-clean-plugin。

  • resource插件maven-resources-plugin,功能就是把項目需要的配置文件拷貝到指定的目錄,默認是拷貝src\main\resources目錄下的件到classes目錄下,當然可以自己來配置源目錄和輸出目錄。

  • compile插件maven-compiler-plugin,執行時先調用resouces插件,功能就是把src\mainjava源碼編譯成字節碼生成class文件,並把編譯好的class文件輸出到target\classes目錄下。

  • 單元測試所用的compile和resources插件和主代碼是相同的,但執行的目標不一樣,testCompile和testResources是把src\test\java下的代碼編譯成字節碼輸出到target\test-classes,同時把src\test\resources下的配置文件拷貝到target\test-classes。

  • package命令完成了項目編譯、單元測試、打包功能,但沒有把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫和遠程maven私服倉庫。mvn clean package依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7個階段。

  • install命令完成了項目編譯、單元測試、打包功能,同時把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫,但沒有佈署到遠程maven私服倉庫。mvn clean install依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8個階段。

  • deploy命令完成了項目編譯、單元測試、打包功能,同時把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫和遠程maven私服倉庫。mvn clean deploy依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9個階段。

二、Maven核心概念

1.工程目錄

Java開發領域普遍認同的一個觀點:約定>配置>編碼(能用配置解決的問題就不編碼,能基於約定的就不配置)

2.POM

Project Object Model:項目對象模型。將 Java 工程的相關信息封裝爲對象作爲便於操作和管理的模型。

這是Maven 工程的核心配置。需要注意的是,這裏指的工程對應的是idea中的module而不是指project。

3.座標

  • Maven 的座標 使用如下三個向量在 Maven 的倉庫中唯一的確定一個 Maven 工程。

    • groupid:公司或組織的域名倒序+當前項目名稱
    • artifactId:當前項目的模塊名稱
    • version:當前模塊的版本
      <groupId>net.xsj.maven</groupId>
      <artifactId>Hello</artifactId>
      <version>1.0.0-SNAPSHOT</version>
    
  • 以連起來的字符串作爲目錄結構到倉庫中查找

net/xsj/maven/Hello/1.0.0-SNAPSHOT/Hello-1.0.0-SNAPSHOT.jar
  
  // 注意:我們自己的 Maven 工程必須執行安裝操作纔會進入倉庫。安裝的命令是:mvn install

4.依賴

  • 依賴的使用:使用 <dependency> 標籤指定被依賴 jar 包的座標
  • 依賴的範圍:有時依賴信息中除了目標 jar 包的座標還有一個 scope 設置,使用標籤<scope>,這就是依賴的範圍。依賴的範圍有幾個可選值,常用的有:compile、test、provided 三個,當然還有不常用的 runtime、system…
    • compile:默認範圍,編譯測試運行都有效
    • provided:在編譯和測試時有效
    • runtime:在測試和運行時有效
    • test:只在測試時有效
    • system:在編譯和測試時有效,與本機系統關聯,可移植性差
  • 依賴的傳遞性:A 依賴 B,B 依賴 C,A 能否使用 C 呢?那要看 B 依賴 C 的範圍是不是 compile,如果是則可用,否則不可用。
  • 依賴的排出:如果我們在當前工程中引入了一個依賴是 A,而 A 又依賴了 B,那麼 Maven 會自動將 A 依賴的 B 引入當 前工程,但是個別情況下 B 有可能是一個不穩定版,或對當前工程有不良影響。這時我們可以在引入 A 的時候將 B 排除。使用的標籤是<exclusions><exclusion>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
  • 統一管理所依賴 jar 包的版本,對同一個框架的一組 jar 包最好使用相同的版本。爲了方便升級框架,可以將 jar 包的版本信息統一提取出來

    // 統一聲明版本號
    <properties>    
        <starfish.spring.version>4.1.1.RELEASE</starfish.spring.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    // 引用前面聲明的版本號
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${starfish.spring.version}</version>
        <scope>compile</scope>
    </dependency>
    

5.倉庫

  • 分類
    • 本地倉庫:爲當前本機電腦上的所有 Maven 工程服務
    • 遠程倉庫
      • 私服:在當前局域網環境下
      • 中央倉庫:架設在 Internet 上,爲全世界所有 Maven 工程服務
      • 中央倉庫鏡像:架設在各個大洲,爲中央倉庫分擔流量。減輕中央倉庫的壓力,同時更快的響應用戶請求。
  • 倉庫中的文件
    • Maven 的插件
    • 我們自己開發的項目的模塊
    • 第三方框架或工具的 jar 包

6.生命週期

  • Maven 生命週期定義了各個構建環節的執行順序,有了這個清單,Maven 就可以自動化的執行構建命令了。

  • Maven 有三套相互獨立的生命週期,分別是:

    • Clean Lifecycle 在進行真正的構建之前進行一些清理工作
    • Default Lifecycle 構建的核心部分,編譯,測試,打包,安裝,部署等等
    • Site Lifecycle 生成項目報告,站點,發佈站點
  • maven的生命週期是相互獨立的,你可以僅僅調用 clean 來清理工作目錄,僅僅調用 site 來生成站點。當然你也可以直接運行 mvn clean install site 運行所有這三套生命週期。 每套生命週期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應於一個特定的階段。

  • 運行任何一個階段的時候,它前面的所有階段都會被運行,例如我們運行 mvn install 的時候,代碼會被編譯,測試,打包。這就是 Maven 爲什麼能夠自動執行構建過程的各個環節的原因。此外,Maven 的插件機制是完全依賴 Maven 的生命週期的。

Maven常用命令

1.maven 命令參數

# 離線模式,相當於以本地模式執行
mvn -o | mvn clean install -o
# 禁用遞歸查找 pom.xml,多 module 工程中可以用來單獨 install 'parent'
mvn -N | mvn clean install -N
# 禁用交互模式(聽說在 jenkins 上可以禁止輸出下載進度?)
mvn -B | mvn clean install -B
# 多 module 工程中指定打包某個 module 和其依賴的 module,若指定多個以逗號分隔
mvn -pl xxx -am | mvn clean package -pl xxx-api -am
# 多 module 工程中指定從某個 module 開始構建,可以和 -pl 聯用
mvn -rf | mvn clean package -rf xxx-api
# 異常時打印堆棧
mvn -e
# 開啓 debug 模式,打開後日志茫茫多,包括 -e 的內容
mvn -X
# 開啓多線程構建,'C' 代表 cpu 核數,'0.5C' 表示有 core/2 個線程,'4' 表示固定 4 個線程
mvn -T 0.5C | mvn -T 4
# 指定 pom.xml 文件路徑
mvn -f
# 指定 settings.xml 文件路徑
mvn -s
# 強制更新依賴
mvn -U
# 強制更新插件
mvn -up
# 禁止更新依賴
mvn -nsu
# 禁止更新插件
mvn -npu
# 激活 profile
mvn -P
# 開啓靜默模式,只輸出異常,某些場景下非常有用
mvn -q | mvn help:evaluate -q -DforceStdout -Dexpression=project.version

2.maven 常用命令

# 打包並拷貝依賴的 jar 包到 target/dependency 下
mvn clean package dependency:copy-dependencies -DincludeScope=compile -DskipTests=true -Dmaven.source.skip=true
# 查看當前激活的 profiles
mvn help:active-profiles
# 獲取 pom.xml 中某個變量的值
mvn help:evaluate -q -DforceStdout -Dexpression=project.version
# 排查 jenkins 問題
mvn -B -U -V -s /media/disk1/fordata/jenkins/tools/maven/conf/settings.xml clean help:active-profiles help:effective-settings help:system -DshowPasswords=true
# release
release:clean release:prepare release:perform -B -N -Darguments="-B -U"
# 生成模塊化工程
mvn archetype:generate -DarchetypeGroupId=kuaishou -DarchetypeArtifactId=java-archetype -DarchetypeVersion=1.0-SNAPSHOT -DarchetypeCatalog=local -DgroupId=com.kuaishou.examples -DartifactId=kuaishou-java-code-examples -Dversion=1.0.0-SNAPSHOT -Dpackage=com.kuaishou.examples
# 查看 maven 插件的文檔
mvn help:describe -Dplugin=war -Dfull=true -Dversion=3.0.0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章