Maven 依赖管理(依赖范围/排除/原则)

       Maven 一个核心的特性就是依赖管理。当我们处理一个或多模块的项目时,模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。

一、依赖配置

       依赖是 Maven中最关键的部分,我们之所以在工程中使用Maven,就是因为它的依赖管理功能。如果我们想要在工程中引入某个jar 包,只需要在 pom.xml 中引入其 jar包的坐标即可。

<project>
    ...
    <dependencies>
        <dependency>
            <groupId>...</groupId>
            <artifactId>...</artifactId>
            <version>...</version>
            <type>...</type>
            <scope>...</scope>
            <optional>...</optional>
            <exclusions>
                <exclusion>
                ...
                </exclusion>
            </exclusions>
        </dependency>
        ...
    </dependencies>
    ...
</project>

    1、groupId、artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖;

    2、type:依赖的类型,对应于项目坐标定义的packaging,大部分情况下,该元素不必声明,其默认值为jar;

    3、scope:依赖的范围,这个内容就比较多一点;

    4、optional:标记依赖是否可选;

    5、exclusions:用来排除传递性依赖。

很多时候,大部分依赖声明只包含groupId、artifactId和version这三个指定基本坐标的元素;而在一些特殊情况下,其它元素至关重要。

二、依赖范围

       依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。

       Maven 提供了六种依赖的范围:compile、test、provided、runtime、system 和import。其中compile 是默认的依赖范围。

在Maven中,我们可以针对 scope要素设置以下依赖范围:

扫描二维码关注公众号,回复: 8565826 查看本文章

      1、compile编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的maven依赖,对于编译 测试 运行三种的classpath都有效。

      2、test测试依赖范围。使用此依赖范围的Maven依赖,只对于测试的classpath有效,在编译主代码或者运行主代码的时候都无法依赖此类依赖。典型的例子是jUnit,它只有在编译测试代码及运行测试代码的时候才有效

      3、provided:以提供依赖范围。使用此依赖范围的maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行的时候,由于容器已经提供,就不需要maven重复地引入一遍。打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作

      4、runtime:运行时依赖范围。使用此依赖范围的maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要jdk提供的jdbc的接口,只有在执行测试或者运行测试的时候才需要实现上述接口的jdbc的驱动

      5、system:系统依赖范围。从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径,该依赖与三种范围的classpath,和provided依赖范围完全一致。可能造成不可移植,谨慎使用。

      6、import:导入依赖范围。该依赖范围不会对三种classpath产生实际影响。只有在dependencyManagement下才有效果。

三、依赖传递性

 1、传递性依赖范围

       在传递性依赖中,假设A依赖B,B依赖C,我们就说A与B是第一直接依赖,B与C是第二直接依赖,C对于A是传递性依赖。

第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围,下面通过一张表格来说明这种传递性依赖范围:

  

     传递性依赖的前提条件是 scope的值为compile

2、A依赖B,B依赖C。当前项目为A,只当B在A项目中的scope,那么c在A中的scope是如何得知呢?

      当C是test或者provided时,C直接被丢弃,A不依赖C;(排除传递依赖),

       否则A依赖C,C的scope继承与B的scope。maven会解析各个依赖的pom,将那些必要的间接依赖,一传递性依赖的形式引入到当前的项目中。

3、多个Maven项目(模块)之间如何依赖

     比如:A项目依赖B项目

       1)将 B项目 install 到本地仓库,供其他项目使用。

       2)在 A项目的pom.xml 引入B项目的依赖(gav)即可使用。

四、依赖排除

        exclusions标签可以包含一个多个exclusion元素,可以排除一个或多个依赖。声明exclusion的时候只需要groupId和artifactId,而不需要version元素。通过引入spring-context依赖演示:

1、引入spring-context依赖,默认包含了beans、core等依赖。

      

2、引入spring-context依赖,排除beans、core依赖。

      

五、依赖原则:为了防止jar包冲突

        由于依赖的内容存在多个版本,如果出现某一个POM依赖多个版本时,则称之为依赖冲突

依赖冲突遵循两个原则:

1、最短路径优先原则(依赖的内容,传递次数越小越优先)

      如果 A依赖于B,B依赖于C,在 B和 C中同时有 log4j的依赖,并且这两个版本不一致时,那么 A会根据最短路径优先原则,在 A中会传递过来 B的log4j版本。或者 通过2- 2)一起演示:

    

2、路径相同时分两种情况

    1)在同一个 pom.xml文件中有两个相同的依赖:后声明则优先(会覆盖前面的),严禁使用

        比如:A项目依赖 spring-context

        

    2)不在同一个 pom.xml文件中有两个相同的依赖:前声明则优先(会覆盖后面的)

        比如:A项目依赖B项目(B依赖 spring-context-5.0.6),同时A项目依赖C项目(C依赖 spring-context-5.0.8)

        将 B、C项目 install 到本地仓库,供A项目使用

         

          

六、统一JDK版本

两种方式

1、通过项目properties右击设置     

2、通过 pom.xml 文件设置

	<build>
		<finalName>comparison-data-project</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

   3、通过修改setting文件,即可,创建Maven项目就用配置好的那个JDK,之前见过

七、统一jar包版本管理

      在 pom.xml使用 properties标签定义一些常量, 方便管理Jar包版本,通过类似 el表达式访问。

      

    在使用Maven时,只是简单知道Maven的用法,从而忽略了其中的一些细节。这里整理下。

ends~

发布了248 篇原创文章 · 获赞 59 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_42402854/article/details/100927675