Maven學習2: 依賴管理

1. 建立一個maven項目

  1. 使用Idea建立一個maven項目java

    • File>New>Project,
    • 左側選擇Maven,右側選擇Project SDK爲1.8,點擊Next
    • 輸入項目GroupId、ArtifactId,點擊Next
    • 點擊Finish
  2. 項目目錄結構
    image.pngweb

    |demo
        |src
            |main
                |java # 源碼目錄
                |resources # 資源目錄
            |test
                |java # 測試源碼目錄
        |pom.xml # 項目配置文件
  3. pom文件spring

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.john.example</groupId>
        <artifactId>demo1</artifactId>
        <version>1.0-SNAPSHOT</version>
    </project>

2. 約定優於配置

  1. 項目目錄結構遵循約定
    建立的maven空項目已經包含了必定的目錄結構,須要開發者遵循這種目錄約定,這是使用maven簡潔配置須要付出的代價。apache

    目錄 說明
    {project.basedir} 存放pom文件和項目子模塊
    {project.basedir}/src/main/java 源碼目錄
    {project.basedir}/src/main/resources 資源目錄
    {project.basedir}/src/test/java 測試源碼目錄
    {project.basedir}/src/test/resources 測試資源目錄
    ${project.basedir}/target 包輸出目錄
    ${project.basedir}/target/classes 編譯輸出目錄
    ${project.basedir}/target/test-classes 測試編譯輸出目錄

3. pom文件

  1. 說明
    POM(Project Object Model,項目對象模型)定義了項目的基本信息,用於描述項目如何構建、聲明項目依賴。
  2. 簡單配置api

    • <?xml>: xml頭信息,定義xml文檔的版本和編碼方式。
    • <project>: 全部pom.xml的根元素,聲明瞭pom相關的命名空間和xsd元素。
    • <modelVersion>: 指定當前pom模型的版本,對於maven2/3,只能是4.0.0。
    • <groupId>: 定義當前maven項目隸屬的實際項目。
    • <artifactId>: 定義實際項目中的一個maven模塊/項目。
    • <version>: 定義maven項目當前所處的版本
    • groupId\artifactId\version: 定義了一個項目基本的座標。
  3. 其餘配置maven

    • 項目依賴
    • 插件
    • 執行目標
    • 項目構建profile

4. maven座標

  1. 說明
    Maven定義了一組規則:世界上任何一個構件均可以使用Maven座標惟一標識。
    Maven座標元素包括groupId, artifactId, version, packaging, classifier
  2. 座標元素ide

    • groupId: 定義當前maven項目隸屬的實際項目。
    • artifactId: 定義實際項目中的一個maven模塊/項目。
    • version: 定義maven項目當前所處的版本。
    • packaging: 定義maven項目的打包方式。打包方式與生成構件的文件擴展名對應,默認爲jar, 經常使用的打包方式有jarwarpom
    • classifier: 幫助定義構建輸出的附屬構件。附屬構件與主構件對應。如demo1-1.0-SNAPSHOT-sources.jar這個構件,包含了主構件的源代碼。不能直接定義項目的classifier,由於附屬構件不是項目直接默認生成的,而是經過附加插件幫助生成的。
  3. 項目構件的文件名測試

    • 通常規則爲: artifactId-version[-classifier].packaging

5. maven依賴

  1. 使用maven怎麼引入依賴?優化

    • 若是要引入第三方jar包,須要知道jar的座標,而後放入pom.xml中的dependencies元素中。
      示例以下:ui

      <project>
          <dependencies>
              <!-- 添加依賴 -->
              <dependency>
                  <groupId></groupId>
                  <artifactId></artifactId>
                  <version></version>
                  <type></type>
                  <scope></scope>
                  <optional></optional>
                  <exclusions>
                      <exclusion></exclusion>
                      <exclusion></exclusion>
                  </exclusions>
              </dependency>
          </dependencies>
      </project>
    • dependencies元素包含多個dependency,每一個dependency表明項目依賴的一個構件信息。
    • dependency元素中的 groupIdartifactIdversion定義了一個構件的基本座標。
    • type被依賴構件的類型,對應於被依賴構件的packaging。默認爲jar, 表示被依賴的構件是一個jar包。
    • scope表示依賴的範圍,參考 2.maven依賴範圍
    • optional表示依賴是否可選,參考可選依賴。
    • exclusions用來排除傳遞依賴。
  2. maven依賴範圍

    依賴範圍就是用來控制依賴與三種classpath(編譯classpath,運行classpath,測試classpath【編譯測試代碼、運行測試代碼】)的關係。
    • compile: 編譯依賴範圍。若是未指定,默認使用該依賴範圍。對於編譯、測試、運行3種classpath都有效。好比spring-web。
    • test: 測試依賴範圍。只對測試classpath有效,在編譯主代碼、運行項目時沒法使用此依賴。好比JUnit。
    • provided: 已提供依賴範圍。對於編譯、測試classpath有效,但在運行時無效。好比servlet-api,在運行項目的時候容器已經提供了。
    • runtime: 運行時依賴範圍。對於測試、運行classpath有效,但在編譯主代碼時無效。好比jdbc驅動實現,運行的時候才須要具體的jdbc驅動實現。
    • system: 系統依賴範圍。該依賴與三種classpath的關係,和provided依賴範圍徹底一致。可是,使用system範圍的依賴時必須經過systemPath元素顯示指定依賴文件的路徑。建議謹慎使用。

      <dependency>
          <groupId>com.john</groupId>
          <artifactId>rt</artifactId>
          <version>1.8</version>
          <scope>system</scope>
          <systemPath>${java.home}/lib/rt.jar</systemPath>
      </dependency>
    • import: 導入依賴範圍。在maven依賴和dependencyManagement時候用到。
  3. 依賴範圍與classpath的關係

    依賴範圍
    (scope)
    對於編譯classpath有效 對於測試classpath有效 對於運行classpath有效 舉例
    compile Y Y Y spring-web
    test -- Y -- JUnit
    provided Y Y -- servlet-api
    runtime -- Y Y JDBC驅動實現
    system Y Y -- 本地的jar包
  4. scope與運行classpath
    scope若是對於運行範圍有效,是指依賴的jar包會被打包到項目的運行包中,最後運行的時候會被添加到classpath中運行。
    若是scope對於運行項目無效,那麼項目打包的時候,這些依賴不會被打包到運行包中。

6. 傳遞性依賴

  1. 說明

    • 在項目中引入groupId:junit, artifactId:junit, version:4.12, scope:test的依賴,查看項目依賴,發現項目依賴junit,而junit又依賴org.hamcrest:hamcrest-core:1.3,該依賴也被自動加進來,這個叫作依賴的傳遞。
    • 假設A依賴於B,B依賴於C,咱們說A對於B是第一直接依賴,B對於C是第二直接依賴,而A對於C是傳遞性依賴
    • 第一直接依賴的範圍和第二直接依賴的範圍決定了傳遞依賴的範圍。
  2. 依賴範圍對傳遞性依賴的影響

    第一直接依賴\第二直接依賴 compile test provided runtime
    compile compile -- -- runtime
    test test -- -- test
    provided provided -- provided provided
    runtime runtime -- -- runtime

7. 依賴調解

  1. 第一原則:路徑近者優先。

    • A->B->C->Y(1.0),A->D->Y(2.0),Y的2.0版本距離A更近一些,因此maven會選擇2.0
  2. 第二原則:第一聲明者優先。

    • A->B->Y(1.0),A->D->Y(2.0),Y的1.0版先聲明,因此maven會選擇1.0版本。

8. 可選依賴

A->B, scope:compile
    B->X, scope:compile,optional:true
    B->Y, scope:compile,optional:true
  • X、Y是可選依賴,依賴不會由B傳至A。X、Y不會對A形成影響。
  • 理想狀況下,不該該使用可選依賴。

9. 依賴管理最佳實踐

  1. 排除依賴

    • 前提

      A->B, scope:compile
          B->C, scope:compile
    • 目的:A不想引入傳遞性依賴C
    • 使用exclusions元素聲明排除依賴,exclusions元素能夠包含多個exclusion元素。
    • 聲明exclusion元素時只須要groupIdartifactId
  2. 歸類依賴

    • 使用properties元素定義maven屬性

      <properties>
          <springframework.version>5.2.1.RELEASE</springframework.version>
      </properties>
  3. 優化依賴

    • 查看當前項目的已解析依賴(Resolved Dependency)

      john:demo1 john$ mvn dependency:list
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ demo1 ---
      [INFO] 
      [INFO] The following files have been resolved:
      [INFO]    org.hamcrest:hamcrest-core:jar:1.3:test
      [INFO]    org.springframework:spring-beans:jar:5.2.1.RELEASE:compile
      [INFO]    org.springframework:spring-core:jar:5.2.1.RELEASE:compile
      [INFO]    org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile
      [INFO]    junit:junit:jar:4.12:test
      [INFO]    org.springframework:spring-web:jar:5.2.1.RELEASE:compile
      [INFO] 
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 0.905 s
      [INFO] Finished at: 2019-12-14T18:34:26+08:00
      [INFO] ------------------------------------------------------------------------
    • 查看當前項目的依賴樹

      john:demo1 john$ mvn dependency:tree
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ demo1 ---
      [INFO] com.john:demo1:jar:1.0-SNAPSHOT
      [INFO] +- org.springframework:spring-web:jar:5.2.1.RELEASE:compile
      [INFO] |  +- org.springframework:spring-beans:jar:5.2.1.RELEASE:compile
      [INFO] |  \- org.springframework:spring-core:jar:5.2.1.RELEASE:compile
      [INFO] |     \- org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile
      [INFO] \- junit:junit:jar:4.12:test
      [INFO]    \- org.hamcrest:hamcrest-core:jar:1.3:test
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 0.938 s
      [INFO] Finished at: 2019-12-14T18:35:31+08:00
      [INFO] ------------------------------------------------------------------------
    • 分析當前項目的依賴

      john:demo1 john$ mvn dependency:analyze
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] >>> maven-dependency-plugin:2.8:analyze (default-cli) > test-compile @ demo1 >>>
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 ---
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      [INFO] skip non existing resourceDirectory /Users/john/Desktop/demo1/demo1/src/main/resources
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo1 ---
      [INFO] Nothing to compile - all classes are up to date
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo1 ---
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      [INFO] skip non existing resourceDirectory /Users/john/Desktop/demo1/demo1/src/test/resources
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo1 ---
      [INFO] Nothing to compile - all classes are up to date
      [INFO] 
      [INFO] <<< maven-dependency-plugin:2.8:analyze (default-cli) < test-compile @ demo1 <<<
      [INFO] 
      [INFO] 
      [INFO] --- maven-dependency-plugin:2.8:analyze (default-cli) @ demo1 ---
      [WARNING] Unused declared dependencies found:
      [WARNING]    org.springframework:spring-web:jar:5.2.1.RELEASE:compile
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 1.285 s
      [INFO] Finished at: 2019-12-14T18:41:43+08:00
      [INFO] ------------------------------------------------------------------------
相關文章
相關標籤/搜索