面試官問我maven package和install的區別

maven package和maven install 有什麼區別?

你經常使用的maven命令有哪些?git

<dependencyManagement> 是幹什麼的?github

還有用過其它構建工具嗎? 和maven有啥區別?web

這幾個問題均可以脫口而出,你應該是有點 maven 能耐,寫代碼去吧,不用看了spring

點贊+收藏 就學會系列,文章收錄在 GitHub JavaEgg ,N線互聯網開發必備技能兵器譜

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 顯示版本信息maven

mvn clean 清空生成的文件ide

mvn compile 編譯 工具

mvn test 編譯並測試 post

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 的核心程序中,在首次使用時須要聯網下載。 下載獲得的插件會被保存到本地倉庫中。本地倉庫默認的位置是:~.m2repository。

5.1. Maven約定的工程目錄:

maven-project.png

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

5.2. POM

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

Maven 工程的核心配置。

5.3. 座標

  • Maven 的座標 使用以下三個向量在 Maven 的倉庫中惟一的肯定一個 Maven 工程。
    • groupid:公司或組織的域名倒序+當前項目名稱
    • artifactId:當前項目的模塊名稱
    • version:當前模塊的版本
<groupId>net.lazyegg.maven</groupId>
  <artifactId>Hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  • 如何經過座標到倉庫中查找 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 包的座標就能夠了。

<dependency>
    <groupId>net.lazyegg.maven</groupId>
    <artifactId>Hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <scope>compile</scope>            
</dependency>
② 依賴的範圍

有時依賴信息中除了目標 jar 包的座標還有一個 scope 設置,這就是依賴的範圍。依賴的範圍有幾個可選值,經常使用的有:compile、test、provided 三個,固然還有不經常使用的 runtime、system..

  • compile默認範圍,編譯測試運行都有效
  • provided:在編譯和測試時有效
  • runtime:在測試和運行時有效
  • test:只在測試時有效
  • system:在編譯和測試時有效,與本機系統關聯,可移植性差
  • 經常使用依賴範圍有效性總結
compile test provided
主程序 ×
測試程序
參與部署 × ×
③ 依賴的傳遞性

A 依賴 B,B 依賴 C,A 可否使用 C 呢?那要看 B 依賴 C 的範圍是否是 compile,若是是則可用,不然不可用。

④ 依賴的排除

若是咱們在當前工程中引入了一個依賴是 A,而 A 又依賴了 B,那麼 Maven 會自動將 A 依賴的 B 引入當 前工程,可是個別狀況下 B 有多是一個不穩定版,或對當前工程有不良影響。這時咱們能夠在引入 A 的時候將 B 排除。

<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>
⑤ 統一管理所依賴 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>
⑥ 依賴的原則:解決 jar 包衝突
  • 路徑最短者優先
  • 路徑相同時先聲明者優先

項目版本衝突時候的那種蛋疼的感受,只有疼過的才知道,因此,咱們來看看疼過的人是怎麼解決的,推薦一個IDEA插件,Maven Helper,比自帶的好用,一目瞭然

maven-helper.png

5.5. 倉庫

  • 分類

    • 本地倉庫:爲當前本機電腦上的全部 Maven 工程服務
    • 遠程倉庫

      • 私服:架設在當前局域網環境下,爲當前局域網範圍內的全部 Maven 工程服務
      • 中央倉庫:架設在 Internet 上,爲全世界全部 Maven 工程服務
      • 中央倉庫的鏡像:架設在各個大洲,爲中央倉庫分擔流量。減輕中央倉庫的壓力,同時更快的響應用戶請求,好比阿里的鏡像
  • 倉庫中的文件

    • Maven 的插件
    • 咱們本身開發的項目的模塊
    • 第三方框架或工具的 jar 包

※ 不論是什麼樣的 jar 包,在倉庫中都是按照座標生成目錄結構,因此能夠經過統一的方式查詢或依賴,查詢地址:http://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 文件的相對路徑
<parent>
     <groupId>com.starfish.maven</groupId>
    <artifactId>Parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 以當前文件爲基準的父工程pom.xml文件的相對路徑 -->
    <relativePath>../Parent/pom.xml</relativePath>
</parent>

此時若是子工程的 groupId 和 version 若是和父工程重複則能夠刪除。

  • 在父工程中管理依賴 將 Parent 項目中的 dependencies 標籤,用 dependencyManagement 標籤括起來
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在子項目中從新指定須要的依賴,刪除範圍和版本號

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

5.9. 聚合

  • 爲何要使用聚合?

將多個工程拆分爲模塊後,須要手動逐個安裝到倉庫後依賴纔可以生效。修改源碼後也須要逐個手動進 行 clean 操做。而使用了聚合以後就能夠批量進行 Maven 工程的安裝、清理工做。

如何配置聚合? 在總的聚合工程中使用 modules/module 標籤組合,指定模塊工程的相對路徑便可

<!-- 配置聚合 -->
<modules>
    <!-- 指定各個子工程的相對路徑 -->
    <module>starfish-learn-grpc</module>
    <module>starfish-learn-kafka</module>
    <module>starfish-web-demo</module>
</modules>
相關文章
相關標籤/搜索