Maven中依赖域标签scope的使用

Maven中依赖域标签scope的使用

在Maven中依赖的域有:compile、provided、runtime、system、test、import

compile属性(默认)

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>5.1.46</version>
     //可省略不写
      <scope>compile</scope>
    </dependency>

compile(编译)表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。

provided属性

当依赖的scope为provided的时候,在编译和测试的时候有效,在执行(mvn package)进行打包时不会加入。
比如, 我们开发一个web应用,在编译时我们需要依赖servlet-api.jar,但是在运行时我们不需要该 jar包,因为这个jar 包已由web服务器提供,如果在打包时又被加入进去,那么就可能产生冲突。此时我们就可以使用 provided 进行范围修饰。

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

system属性

与provided相同,不过被依赖项不会从maven仓库获取,而是从本地文件系统拿,需要配合systemPath属性使用。比如:

<dependency>
    <groupId>org.open</groupId>
    <artifactId>open-core</artifactId>
    <version>1.5</version>
    <scope>system</scope>
    <systemPath>${basedir}/WebContent/WEB-INF/lib/open-core.jar</systemPath>
</dependency>

runtime属性

依赖仅参与运行周期中的使用。一般这种类库都是接口与实现相分离的类库,比如JDBC类库,在编译之时仅依赖相关的接口,在具体的运行之时,才需要具体的mysql、oracle等等数据的驱动程序。 此类的驱动都是为runtime的类库。
与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API jar是compile的,具体实现是runtime的,compile只需要知道接口就足够了。oracle jdbc驱动架包就是一个很好的例子,一般scope为runntime。另外runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.46</version>
           <scope>runtime</scope>
       </dependency>

test属性

当依赖的scope为test的时候,指的的是在测试范围有效,在编译与打包的时候都不会使用这个依赖。相当于在打包阶段做了exclude的动作。

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

import属性

import依赖范围不会像test、compile、runtime依赖范围,对项目的 依赖产生直接的影响。
它的作用是将其他模块中的 dependencyManagement 导入当前 Maven 项目 pom 的 dependencyManagement 中。例如存在一个Maven 工程com.maven.first,它的 pom 中的 dependencyManagement 配置如下:

<project>
    ...
    <groupId>com.maven</groupId>
    <artifactId>first</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    ...
    <dependencyManagement>
        <dependencies>
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${project.build.spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    ...
</project>

而另一个Maven 工程 com.maven.second,需要引用 first 工程的 pom 中定义的 dependencyManagement ,除了复制、继承之外,还可以编写如下配置,将它们导入进去。

<!-- 使用这种方式更灵活,但需要添加编译插件1.8版本的声明,否则默认为1.5 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.maven</groupId>
            <artifactId>first</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<!--
 依赖范围import只在dependencyManagement元素下才有效果,使用该范围的依赖通常指向一个pom,作用是将目标pom中的dependencyManagement配置导入并合并到当前pom的dependencyManagement配置。
 -->

注意:scope的import 属性只能在dependencyManagement 中使用,并且type的类型是pom,表示将其它的pom文件中dependencyManagement管理的依赖全部复制到当前文件中的dependencyManagement区域中,进行依赖的版本锁定。
此时即使引入文件中的version中使用的是propertise定义的版本变量,也是可以成功引入的。

scope的依赖传递

A–>B–>C。当前项目为A,A项目依赖于项目B,B项目依赖于项目C。知道项目B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
当C是test或者provided时,C依赖会被直接丢弃,A不依赖C;
否则A依赖C,C的scope继承于B的scope。

传递依赖失效示意图:

- 传递依赖 complie provided runtime test
直接依赖 - - - - -
complie - complie 失效 runtime 失效
provided - provided provided provided 失效
runtime - runtime 失效 runtime 失效
test - test 失效 test 失效

参考文章链接

1、https://www.programminghunter.com/article/5007542247/
2、https://blog.csdn.net/u013912696/article/details/103755236

你可能感兴趣的:(maven,java)