13161216443

您所在位置: 首頁> 學習課程> java培訓 | Maven系列第3篇:詳解maven解決依賴問題

java培訓 | Maven系列第3篇:詳解maven解決依賴問題

發布百知教育 來源:學習課程 2019-11-13

maven系列目標:從入門開始開始掌握一個高級開發所需要的maven技能。

這是maven系列第3篇。

我們先來回顧一下什么是maven?

maven是apache軟件基金會組織維護的一款自動化構件工具,專注服務于java平臺的項目構件和依賴管理。


本文主要內容

  1. 感受一下maven的效果

  2. maven約定配置

  3. maven中pom文件

  4. maven坐標詳解

  5. maven依賴導入功能

  6. maven依賴范圍詳解

  7. maven依賴的傳遞

  8. maven中依賴調解功能

  9. 可選依賴(optional元素)的使用

  10. 排除依賴的使用

先來感受一下maven的神奇

安裝maven3.6.10

上篇文章中安裝的是Maven3.6.2版本,這個版本在運行過程中會有一些問題,請大家按照上一篇文章的介紹重新安裝3.6.1版本。

idea中配置maven

先說幾句,如果你使用的是eclipse,建議你去嘗試使用一下idea,非常優秀的一款開發工具,后面我們一直采用idea作為開發工具來講解案例,建議大家也使用這個。

打開idea,點擊File->setting

java培訓



按照如下配置maven的信息,點擊“ok”,idea中maven配置完成

注意"Maven home directory"選擇我們上面安裝的3.6.1

User settings file 和 Local repository 我們使用用戶級別的。


java培訓


使用mven創建一個springboot項目

我們來創建一個web項目,然后輸出一句話,我們采用maven的方式來創建看看有多簡單。

打開idea,點擊File->New->Project,選擇Spring Initializr,如下:


java培訓


點擊"Next",如下圖,按照圖中的信息輸入,點擊"Next":

咱們先不用關注需要輸入的信息具體是什么意思,后面會講解。


java培訓


選擇springboot版本,勾選"Lombook"、"Spring Web",如下圖:


java培訓

java培訓



點擊"Next"->"Finish"完成springboot項目的創建,如下圖:


java培訓


刪掉下圖中無關的文件

按住Shift健,多選,然后點擊Del健刪除。


java培訓




新建一個Controller類:

package com.javacode2018.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
    @RequestMapping("")
    public String index() {
        return "你好,歡迎你和【路人甲Java】一起學些Maven相關技術!";
    }
}

springboot-chat01目錄中打開cmd窗口,執行下面命令

mvn spring-boot:run

cmd中輸出如下:

D:\code\IdeaProjects\springboot-chat01>mvn spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< com.javacode2018:springboot-chat01 >-----------------
[INFO] Building springboot-chat01 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.2.1.RELEASE:run (default-cli) > test-compile @ springboot-chat01 >>>
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ springboot-chat01 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ springboot-chat01 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to D:\code\IdeaProjects\springboot-chat01\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ springboot-chat01 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\code\IdeaProjects\springboot-chat01\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ springboot-chat01 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to D:\code\IdeaProjects\springboot-chat01\target\test-classes
[INFO]
[INFO] <<< spring-boot-maven-plugin:2.2.1.RELEASE:run (default-cli) < test-compile @ springboot-chat01 <<<
[INFO]
[INFO]
[INFO] --- spring-boot-maven-plugin:2.2.1.RELEASE:run (default-cli) @ springboot-chat01 ---
[INFO] Attaching agents: []

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.1.RELEASE)

2019-11-11 14:43:58.758  INFO 19004 --- [           main] c.j.SpringbootChat01Application          : Starting SpringbootChat01Application on DESKTOP-3OB6NA3 with PID 19004 (D:\code\IdeaProjects\springboot-chat01\target\classes started by Think in D:\code\IdeaProjects\springboot-chat01)
2019-11-11 14:43:58.761  INFO 19004 --- [           main] c.j.SpringbootChat01Application          : No active profile set, falling back to default profiles: default
2019-11-11 14:44:01.116  INFO 19004 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-11-11 14:44:01.125  INFO 19004 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-11-11 14:44:01.125  INFO 19004 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.27]
2019-11-11 14:44:01.213  INFO 19004 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-11-11 14:44:01.213  INFO 19004 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2417 ms
2019-11-11 14:44:01.339  INFO 19004 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-11-11 14:44:01.457  INFO 19004 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-11-11 14:44:01.460  INFO 19004 --- [           main] c.j.SpringbootChat01Application          : Started SpringbootChat01Application in 2.972 seconds (JVM running for 3.348)
2019-11-11 14:44:25.892  INFO 19004 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-11-11 14:44:25.892  INFO 19004 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-11-11 14:44:25.896  INFO 19004 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms

瀏覽器中訪問

http://localhost:8080/

效果如下:


java培訓



上面整個過程中,我們基本上沒寫什么代碼,沒有去添加springmvc相關的jar,然后很快就寫了一個springmvc的例子來。

以往我們做一個springmvc項目,我們需要添加很多springmvc相關的jar,然后將其復制到項目的lib下面,然后添加到classpath中,期間還有可能出現jar版本沖突、jar包不全的問題,導致我們花費很多時間在解決jar包的問題上。

而上面我們使用了maven,通過maven這些問題都解決了,上面我們創建項目之后,有一個非常重要的文件pom.xml,大家可以打開看一下,如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.javacode2018</groupId>
    <artifactId>springboot-chat01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-chat01</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

上面的pom.xml是自動生成的,作用是將springmvc所有需要的包都自動導入了,并且還為我們提供了支持mvn spring-boot:run啟動的功能,是不是很神奇,這些功能都是通過maven來實現的,通過pom來進行配置,maven會讀取pom中的配置信息,來加載我們項目中需要依賴的jar包,還有需要如何構件項目等等信息,都可以在pom文件中進行配置。

關于mvn spring-boot:run是如何啟動項目的,這個后面學到maven聲明周期和插件的時候,一切您都會明白的,敬請期待。

用過ant的都知道,ant中有個build.xml文件需要配置,而pom.xml文件類似于build.xml的功能,不過不是給ant執行的,而是給maven去執行的,maven說你們如果需要用我來幫你們解決版本依賴問題、幫你們解決jar沖突的問題、幫你們打包、部署,那你們都必須要給我提供一個pom.xml配置文件,并且項目結構也必須按照我指定的結構來,我只認pom.xml文件。而之前我們使用ant的時候,項目源碼、資源文件、輸出目錄、打包目錄所在的位置都是自己隨意指定的,所以需要我們自己去寫很多配置,相當麻煩。而maven中這些位置都是約定好的,這就是約定配置,如下。

約定配置

Maven 提倡使用一個共同的標準目錄結構,Maven 使用約定優于配置的原則,大家盡可能的遵守這樣的目錄結構,如下所示:


java培訓


大家結合上面表格中的信息,再去看看springboot-chat01項目的結構,這是maven項目標準的結構,大家都按照這個約定來,然后maven中打包、運行、部署時候就非常方便了,maven他自己就知道你項目的源碼、資源、測試代碼、打包輸出的位置,這些都是maven規定好的,就不是你隨意搞的一個結構,所以不需要我們再去配置了,所以使用maven去打包、部署、運行都是非常方便的。

這塊現實中也有很多案例,比如USB接口,電壓,這些都是規定好的,如果USB接口所有廠商制造的大小都不一致,那我們使用電子設備的時候是相當難受的。

pom文件

當我們在項目中需要用到maven幫我們解決jar包依賴問題,幫我們解決項目中的編譯、測試、打包、部署時,項目中必須要有pom.xml文件,這些都是依靠pom的配置來完成的。

POM( Project Object Model,項目對象模型 ) 是 Maven 工程的基本工作單元,是一個XML文件,包含了項目的基本信息,用于描述項目如何構件,聲明項目依賴,等等。

執行任務或目標時,Maven 會在當前目錄中查找 POM。它讀取 POM,獲取所需的配置信息,然后執行目標。

POM 中可以指定以下配置:

  • 項目依賴

  • 插件

  • 執行目標

  • 項目構件 profile

  • 項目版本

  • 項目開發者列表

  • 相關郵件列表信息

在創建 POM 之前,我們首先需要描述項目組 (groupId),項目的唯一ID。

<?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.javacode2018</groupId>
    <!--項目的唯一ID,一個groupId下面可能多個項目,就是靠artifactId來區分的-->
    <artifactId>maven-chat02</artifactId>

    <!-- 版本號 -->
    <version>1.0-SNAPSHOT</version>

</project>

pom的內容比較多,我們慢慢講,大家慢慢吸收,利于消化。

maven坐標

maven中引入了坐標的概念,每個構件都有唯一的坐標,我們使用maven創建一個項目需要標注其坐標信息,而項目中用到其他的一些構件,也需要知道這些構件的坐標信息。

maven中構件坐標是通過一些元素定義的,他們是groupId、artifactId、version、packaging、classifier,如我們剛剛上面創建的springboot項目,它的pom中坐標信息如下:

<groupId>com.javacode2018</groupId>
<artifactId>springboot-chat01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

goupId:定義當前構件所屬的組,通常與域名反向一一對應。

artifactId:項目組中構件的編號。

version:當前構件的版本號,每個構件可能會發布多個版本,通過版本號來區分不同版本的構件。

package:定義該構件的打包方式,比如我們需要把項目打成jar包,采用java -jar去運行這個jar包,那這個值為jar;若當前是一個web項目,需要打成war包部署到tomcat中,那這個值就是war,可選(jar、war、ear、pom、maven-plugin),比較常用的是jar、war、pom,這些后面會詳解。

上面接元素中,groupId、artifactId、version是必須要定義的,packeage可以省略,默認為jar。

我們可以將上面創建的springboot項目發布出去,然后只需要告訴別人springboot-chat01這個項目的坐標信息,其他人就可以直接使用了,而且其他人用的時候,不用關心springboot-chat01運行需要依賴什么,springboot-chat01依賴的這些都會自動導入,非常方便。

maven導入依賴的構件

maven可以幫我們引入需要依賴的構件(jar等),而maven是如何定位到某個構件的呢?

項目中如果需要使用第三方的jar,我們需要知道其坐標信息,然后將這些信息放入pom.xml文件中的dependencies元素中:

<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中groupId、artifactId、version是定位一個構件必須要提供的信息,所以這幾個是必須的

  • type:依賴的類型,表示所要依賴的構件的類型,對應于被依賴的構件的packaging。大部分情況下,該元素不被聲明,默認值為jar,表示被依賴的構件是一個jar包。

  • scope:依賴的范圍,后面詳解

  • option:標記依賴是否可選,后面詳解

  • exclusions:用來排除傳遞性的依賴

通常情況下我們依賴的都是一些jar包,所以大多數情況下,只需要提供groupId、artifactId、version信息就可以了。

創建一個maven項目(maven-chat02)

打開idea,點擊File->New->Project,選擇Maven,如下:


java培訓


點擊Next,輸入項目的maven坐標信息,如下:


java培訓


點擊Next->Finish,完成項目的創建,項目結構如下:


java培訓


打開pom.xml,引入springmvc依賴,如下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

pom.xml文件最終如下:

<?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.javacode2018</groupId>
    <artifactId>maven-chat02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

可以看到我們只引入了一個spring-web的jar包,springmvc還需要spring-core等jar包的支持,我們來看一下,maven是否幫我們也導入了。

pom.xml文件中,右鍵選中Show Dependencies,可以顯示當前項目依賴的jar包,如下:


java培訓

java培訓


上圖中顯示了項目中的依賴信息,箭頭有多級,從左向右,第一個箭頭表示第一級,是直接依賴,后面的都是間接依賴,屬于傳遞性依賴。

我們在maven-chat02中添加了spring-web的依賴,并沒有引入spring-beans、spring-core、spring-jcl的依賴,但是maven都自動幫我們導入了,這是因為spring-web的pom.xml中定義了它自己的依賴,當我們使用spring-web的時候,spring-web需要依賴的jar也會自動被依賴進來,maven是不是很強大。

如果沒有maven,我們找jar是相當痛苦的,經常會出現少添加了一些jar,或者依賴的jar版本對不上等問題,而maven直接幫我們解決了。

maven依賴范圍(scope)

我們的需求:

  1. 我們在開發項目的過程中,可能需要用junit來寫一些測試用例,此時需要引入junit的jar包,但是當我們項目部署在線上運行了,測試代碼不會再執行了,此時junit.jar是不需要了,所以junit.jar只是在編譯測試代碼,運行測試用例的時候用到,而上線之后用不到了,所以部署環境中是不需要的

  2. 我們開發了一個web項目,在項目中用到了servlet相關的jar包,但是部署的時候,我們將其部署在tomcat中,而tomcat中自帶了servlet的jar包,那么我們的需求是開發、編譯、單元測試的過程中需要這些jar,上線之后,servlet相關的jar由web容器提供,也就是說打包的時候,不需要將servlet相關的jar打入war包了

  3. 像jdbc的驅動,只有在運行的時候才需要,編譯的時候是不需要的

這些需求怎么實現呢?

我們都知道,java中編譯代碼、運行代碼都需要用到classpath變量,classpath用來列出當前項目需要依賴的jar包,這塊不清楚的可以去看一下classpath和jar。

classpath和jar關系詳解:http://www.itsoku.com/article/234

maven用到classpath的地方有:編譯源碼、編譯測試代碼、運行測試代碼、運行項目,這幾個步驟都需要用到classpath。

如上面的需求,編譯、測試、運行需要的classpath對應的值可能是不一樣的,這個maven中的scope為我們提供了支持,可以幫我們解決這方面的問題,scope是用來控制被依賴的構件與classpath的關系(編譯、打包、運行所用到的classpath),scope有以下幾種值:

compile

編譯依賴范圍,如果沒有指定,默認使用該依賴范圍,對于編譯源碼、編譯測試代碼、測試、運行4種classpath都有效,比如上面的spring-web。

test

測試依賴范圍,使用此依賴范圍的maven依賴,只對編譯測試、運行測試的classpath有效,在編譯主代碼、運行項目時無法使用此類依賴。比如junit,它只有在編譯測試代碼及運行測試的時候才需要。

provide

已提供依賴范圍。表示項目的運行環境中已經提供了所需要的構件,對于此依賴范圍的maven依賴,對于編譯源碼、編譯測試、運行測試中classpath有效,但在運行時無效。比如上面說到的servlet-api,這個在編譯和測試的時候需要用到,但是在運行的時候,web容器已經提供了,就不需要maven幫忙引入了。

runtime

運行時依賴范圍,使用此依賴范圍的maven依賴,對于編譯測試、運行測試和運行項目的classpath有效,但在編譯主代碼時無效,比如jdbc驅動實現,運行的時候才需要具體的jdbc驅動實現。

system

系統依賴范圍,該依賴與3中classpath的關系,和provided依賴范圍完全一致。但是,使用system范圍的依賴時必須通過systemPath元素顯示第指定依賴文件的路徑。這種依賴直接依賴于本地路徑中的構件,可能每個開發者機器中構件的路徑不一致,所以如果使用這種寫法,你的機器中可能沒有問題,別人的機器中就會有問題,所以建議謹慎使用。

如下:

<dependency>
    <groupId>com.javacode2018</groupId>
    <artifactId>rt</artifactId>
    <version>1.8</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>

import

這個比較特殊,后面的文章中單獨講,springboot和springcloud中用到的比較多。

依賴范圍與classpath的關系如下:


java培訓班


scope如果對于運行范圍有效,意思是指依賴的jar包會被打包到項目的運行包中,最后運行的時候會被添加到classpath中運行。如果scope對于運行項目無效,那么項目打包的時候,這些依賴不會被打包到運行包中。

依賴的傳遞

上面我們創建的maven-chat02中依賴了spring-web,而我們只引入了spring-web依賴,而spring-web又依賴了spring-beans、spring-core、spring-jcl,這3個依賴也被自動加進來了,這種叫做依賴的傳遞。

不過上面我們說的scope元素的值會對這種傳遞依賴會有影響。

假設A依賴于B,B依賴于C,我們說A對于B是第一直接依賴,B對于C是第二直接依賴,而A對于C是傳遞性依賴,而第一直接依賴的scope和第二直接依賴的scope決定了傳遞依賴的范圍,即決定了A對于C的scope的值。

下面我們用表格來列一下這種依賴的效果,表格最左邊一列表示第一直接依賴(即A->B的scope的值),而表格中的第一行表示第二直接依賴(即B->C的scope的值),行列交叉的值顯示的是A對于C最后產生的依賴效果。


java培訓


解釋一下:

  1. 比如A->B的scope是compile,而B->C的scope是test,那么按照上面表格中,對應第2行第3列的值-,那么A對于C是沒有依賴的,A對C的依賴沒有從B->C傳遞過來,所以A中是無法使用C的

  2. 比如A->B的scope是compile,而B->C的scope是runtime,那么按照上面表格中,對應第2行第5列的值為runtime,那么A對于C是的依賴范圍是runtime,表示A只有在運行的時候C才會被添加到A的classpath中,即對A進行運行打包的時候,C會被打包到A的包中

  3. 大家仔細看一下,上面的表格是有規律的,當B->C依賴是compile的時候(表中第2列),那么A->C的依賴范圍和A->B的sope是一樣的;當B->C的依賴是test時(表中第3列),那么B->C的依賴無法傳遞給A;當B->C的依賴是provided(表第4列),只傳遞A->C的scope為provided的情況,其他情況B->C的依賴無法傳遞給A;當B->C的依賴是runtime(表第5列),那么C按照B->C的scope傳遞給A

  4. 上面表格大家多看幾遍,理解理解

maven依賴調解功能

現實中可能存在這樣的情況,A->B->C->Y(1.0),A->D->Y(2.0),此時Y出現了2個版本,1.0和2.0,此時maven會選擇Y的哪個版本?

解決這種問題,maven有2個原則:

路徑最近原則

上面A->B->C->Y(1.0),A->D->Y(2.0),Y的2.0版本距離A更近一些,所以maven會選擇2.0。

但是如果出現了路徑是一樣的,如:A->B->Y(1.0),A->D->Y(2.0),此時maven又如何選擇呢?

最先聲明原則

如果出現了路徑一樣的,此時會看A的pom.xml中所依賴的B、D在dependencies中的位置,誰的聲明在最前面,就以誰的為主,比如A->B在前面,那么最后Y會選擇1.0版本。

這兩個原則希望大家記?。郝窂阶罱瓌t、最先聲明原則。

可選依賴(optional元素)

有這么一種情況:

A->B中scope:compile
B->C中scope:compile

按照上面介紹的依賴傳遞性,C會傳遞給A,被A依賴。

假如B不想讓C被A自動依賴,可以怎么做呢?

dependency元素下面有個optional,是一個boolean值,表示是一個可選依賴,B->C時將這個值置為false,那么C不會被A自動引入。

排除依賴

A項目的pom.xml中

<dependency>
    <groupId>com.javacode2018</groupId>
    <artifactId>B</artifactId>
    <version>1.0</version>
</dependency>

B項目1.0版本的pom.xml中

<dependency>
    <groupId>com.javacode2018</groupId>
    <artifactId>C</artifactId>
    <version>1.0</version>
</dependency>

上面A->B的1.0版本,B->C的1.0版本,而scope都是默認的compile,根據前面講的依賴傳遞性,C會傳遞給A,會被A自動依賴,但是C此時有個更新的版本2.0,A想使用2.0的版本,此時A的pom.xml中可以這么寫:

<dependency>
    <groupId>com.javacode2018</groupId>
    <artifactId>B</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.javacode2018</groupId>
            <artifactId>C</artifactId>
        </exclusion>
    </exclusions>
</dependency>

上面使用使用exclusions元素排除了B->C依賴的傳遞,也就是B->C不會被傳遞到A中。

exclusions中可以有多個exclusion元素,可以排除一個或者多個依賴的傳遞,聲明exclusion時只需要寫上groupId、artifactId就可以了,version可以省略。


注釋:本文內容來自公眾號路人甲java


java培訓班:http://www.akpsimsu.com/java2019



上一篇:UI設計培訓 | 交互設計師如何在陌生領域做好設計?

下一篇:應屆生去公司找個Java程序員的職位需要什么技能?

相關推薦

www.akpsimsu.com

有位老師想和您聊一聊

關閉

立即申請