美文网首页
Maven学习笔记(二):Maven依赖

Maven学习笔记(二):Maven依赖

作者: 简单一点点 | 来源:发表于2019-05-07 21:48 被阅读0次

    依赖是Maven中最关键的部分,使用Maven管理项目很大的原因是因为他的依赖管理功能。

    全部章节传送门:
    Maven学习笔记(一):Maven概述
    Maven学习笔记(二):Maven依赖
    Maven学习笔记(三):POM文件
    Maven学习笔记(四):Maven仓库
    Maven学习笔记(五):Maven插件

    在工程中引入某个jar包,只需要在pom.xml中引入jar包的坐标,比如引入log4j的依赖:

    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    

    Maven通过groupId、artifactId与version三个向量来定位Maven仓库其jar包所在的位置,并把对应的jar包引入到工程中来。

    依赖范围

    maven 项目不同的阶段引入到classpath中的依赖是不同的,例如,编译时,maven 会将与编译相关的依赖引入classpath中,测试时,maven会将测试相关的的依赖引入到classpath中,运行时,maven会将与运行相关的依赖引入classpath中,而依赖范围就是用来控制依赖于这三种classpath的关系。

    前面的例子中,scope标签就是依赖范围的配置。该项默认配置compile,可选配置还有test、provided、runtime、system、import,其中compile、test和provided使用较多,下面依次介绍。

    编译依赖范围(compile)

    该范围就是默认依赖范围,此依赖范围对于编译、测试、运行三种classpath都有效,举个简单的例子,假如项目中有spring-core的依赖,那么spring-core不管是在编译,测试,还是运行都会被用到,因此spring-core必须是编译范围(构件默认的是编译范围,所以依赖范围是编译范围的无须显示指定)

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>2.5</version>
        <scope>compile</scope> <!--默认为该依赖范围,无须显示指定-->
    </dependency>
    

    测试依赖范围(test)

    使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最典型的例子就是 Junit, 构件在测试时才需要,所以它的依赖范围是测试,因此它的依赖范围需要显示指定为<scope>test</scope>,当然不显示指定依赖范围也不会报错,但是该依赖会被加入到编译和运行的classpath中,造成不必要的浪费 。

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <scope>test</scope>
    </dependency>
    

    已提供依赖范围(provided)

    使用该依赖范围的maven依赖,只对编译和测试的classpath有效,对运行的classpath无效,典型的例子就是servlet-api, 编译和测试该项目的时候需要该依赖,但是在运行时,web容器已经提供的该依赖,所以运行时就不再需要此依赖,如果不显示指定该依赖范围,并且容器依赖的版本和maven依赖的版本不一致的话,可能会引起版本冲突,造成不良影响。

    <dependency>
        <groupId>javax-servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    

    运行时依赖范围(runtime)

    使用该依赖范围的maven依赖,只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动。

    系统依赖范围(system)

    该依赖与classpath的关系与provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量:

    <dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stext</artifactId>
        <version>2.0</version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/rt.jar</systemPath> 
    </dependency>
    

    导入依赖范围(import)

    该依赖范围不会对三种classpath产生影响,该依赖范围只能与dependencyManagement元素配合使用,其功能为将目标pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中。有关dependencyManagement的功能会在Maven继承特性部分说明。

    依赖的传递

    依赖的传递性指:在A中添加对B的依赖,在B中添加对C的依赖,如果依赖范围是compile的,A不仅会有B的jar 包,也会有C的jar 包。如果在C中添加了某个依赖,那么根据传递性,A和B也可以使用C添加的依赖,而不需要自己再重新引入依赖。

    依赖传递的原则:

    • 最短路径优先原则:如果A依赖于B,B依赖于C,在B和C 中同时有log4j的依赖,并且这两个版本不一致,那么A会根据最短路径原则,在A中会传递过来B的log4j版本。
    • 路径相同先声明原则:如果在A同时依赖于B和C,B和C没有依赖关系,并且都有log4j的依赖,且版本不一致,那么A会引入在pom.xml中先声明依赖的log4j版本。

    依赖的排除

    我们在当前工程中引入了A的依赖,而A同时有对B的依赖,根据传递性我们知道,在当前工程中会自动引入对B的依赖。如果我们不想引入对B的依赖,我们就需要在引入对A依赖的同时排除对B的依赖。

    下面我们以spring-core为例,当我们在pom.xml中引入对spring-core 的同时,会自动将commons-logging 的jar 包引入进来,如果我们不想引入commons-logging,就可以进行如下配置:

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.14.RELEASE</version>
    
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exlcusion>
            </exclusions>
        </dependency>
    </dependencies>
    

    聚合和继承

    将多个项目同时运行就称为聚合。只需在pom文件中作如下配置即可实现聚合:

    <modules>
        <module>web-connection-pool</module>
        <module>web-java-crawler</module>
    </modules>
    

    另外,聚合模块的打包方式必须为pom,否则无法完成构建

    在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。,父模块的打包方式必须为pom,否则无法构建项目。

    通过在各个子模块中配置来表明其继承与哪一个父模块:

    <parent>
       <groupId>com.baidu</groupId>
       <artifactId>miliao-rootpom</artifactId> 
       <version>2.0.3</version>
    </parent>
    

    继承的POM元素如下:

    • groupId:项目组ID,项目坐标的核心元素
    • version:项目版本,项目坐标的核心因素
    • description:项目的描述信息
    • organization:项目的组织信息
    • inceptionYear:项目的创始年份
    • url:项目的URL地址
    • developers:项目的开发者信息
    • contributors:项目的贡献者信息
    • distributionManagement:项目的部署配置
    • issueManagement:项目的缺陷跟踪系统信息
    • ciManagement:项目的持续集成系统信息
    • scm:项目的版本控制系统
    • malilingLists:项目的邮件列表信息
    • properties:自定义的Maven属性
    • dependencies:项目的依赖配置
    • dependencyManagement:项目的依赖管理配置
    • repositories:项目的仓库配置
    • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
    • reporting:包括项目的报告输出目录配置、报告插件配置等

    相关文章

      网友评论

          本文标题:Maven学习笔记(二):Maven依赖

          本文链接:https://www.haomeiwen.com/subject/pjjuoqtx.html