zoukankan      html  css  js  c++  java
  • scope为provided

    以下面dependency为例

    1 <dependency>
    2     <groupId>javax.servlet</groupId>
    3     <artifactId>javax.servlet-api</artifactId>
    4     <version>3.1.0</version>
    5     <scope>provided</scope>
    6 </dependency>

    当子工程中引入某个依赖时,可见其设置<scope>provided</scope>,那么后续依赖该工程的所有项目会可能出现找不到这个依赖,原因是:

    1.provided是没有传递性的。即,如果你依赖的某个jar包,它的某个jar的范围是provided,那么该jar不会在你的工程中依靠jar依赖传递加入到你的工程中。

    2.provided具有继承性,上面的情况,如果需要统一配置一个组织的通用的provided依赖,可以使用parent,然后在所有工程中继承

    比如:我现在有个工程结构图如下:

     假设GranParent中的pom.xml是个超级pom.xml文件,

    Parent继承GranParent

     1 <modelVersion>4.0.0</modelVersion>
     2 <groupId>com.alice</groupId>
     3 <artifactId>Parent</artifactId>
     4 <version>1.0.0-SNAPSHOT</version>
     5 
     6 <parent>
     7     <groupId>com.alice</groupId>
     8     <artifactId>GrandParent</artifactId>
     9     <version>1.0.0</version>
    10 </parent>
    11 
    12 <modules>
    13     <module>childA</module>
    14     <module>childB</module>
    15     <module>childB</module>
    16 </modules>
    17 <packaging>pom</packaging>

    childA的pom.xml

     1 <parent>
     2       <groupId>com.alice</groupId>
     3       <artifactId>Parent</artifactId>
     4       <version>1.0.0-SNAPSHOT</version>
     5 </parent>
     6 <artifactId>childA</artifactId>
     7     
     8  <name>childA</name>
     9  <packaging>jar</packaging>
    10 
    11 <dependencies>        
    12        <dependency>
    13            <groupId>javax.servlet</groupId>
    14           <artifactId>javax.servlet-api</artifactId>
    15           <version>3.1.0</version>
    16           <scope>provided</scope>
    17       </dependency>
    18 <dependencies>

    childB的pom.xml,其中依赖childA

     1 <modelVersion>4.0.0</modelVersion>
     2  <parent>
     3     <groupId>com.alice</groupId>
     4     <artifactId>Parent</artifactId>
     5     <version>1.0.0-SNAPSHOT</version>
     6  </parent>
     7  <artifactId>childB</artifactId>
     8   
     9  <name>childB</name>
    10  <packaging>jar</packaging>
    11 
    12  <dependencies>
    13       <dependency>
    14         <groupId>com.alice</groupId>
    15         <artifactId>childA</artifactId>
    16         <version>1.0.0-SNAPSHOT</version>
    17     </dependency>
    18  </dependencies>

    childC的pom.xml,其中依赖childB

     1 <modelVersion>4.0.0</modelVersion>
     2  <parent>
     3     <groupId>com.alice</groupId>
     4     <artifactId>Parent</artifactId>
     5     <version>1.0.0-SNAPSHOT</version>
     6  </parent>
     7  <artifactId>childC</artifactId>
     8   
     9  <name>childC</name>
    10  <packaging>jar</packaging>
    11 
    12  <dependencies>
    13       <dependency>
    14         <groupId>com.alice</groupId>
    15         <artifactId>childB</artifactId>
    16         <version>1.0.0-SNAPSHOT</version>
    17     </dependency>
    18  </dependencies>

    从上面的pom文件可知,

    在childA中,javax.servlet的scope为provided

    首先解释下为啥设置为provided:

      因为是tomcat中也有servlet-api包,如果默认为compile,即项目在编译,测试,运行阶段都需要这个artifact对应的jar包在classpath中,那么在使用tomcat运行时就会发生了冲突,由于provided只影响编译和测试阶段,在编译测试阶段,我们需要这个artifact对应的jar包在classpath中,而在运行阶段,假定目标的容器(比如我们这里的tomcat容器)已经提供了这个jar包,所以无需我们这个artifact对应的jar包了,那么在实际发布时会默认使用第三方web服务器中提供的jar包,而不会使用本jar包。

    由于childB直接依赖childA,所以childB在测试编译阶段可引入servlet-api包,程序可以正常跑通,

    但是childC依赖B,而childC也是需要childA中的servlet-api包,但是由于provided没有传递性,scope在不指明情况下默认为copmpile,所以childC和childA是间接依赖关系,所以childC无法引用servlet-api包,导致运行报错,此时需要单独在childC中加servlet-api依赖包,

     1 <modelVersion>4.0.0</modelVersion>
     2  <parent>
     3     <groupId>com.alice</groupId>
     4     <artifactId>Parent</artifactId>
     5     <version>1.0.0-SNAPSHOT</version>
     6  </parent>
     7  <artifactId>childC</artifactId>
     8   
     9  <name>childC</name>
    10  <packaging>jar</packaging>
    11 
    12  <dependencies>
    13       <dependency>
    14         <groupId>com.alice</groupId>
    15         <artifactId>childB</artifactId>
    16         <version>1.0.0-SNAPSHOT</version>
    17     </dependency>
    18     <dependency>
    19        <groupId>javax.servlet</groupId>
    20        <artifactId>javax.servlet-api</artifactId>
    21        <version>3.1.0</version>
    22        <scope>test</scope>
    23      </dependency>
    24  </dependencies>

    什么是传递性依赖(https://blog.csdn.net/lewky_liu/article/details/78145211)
    有时候我们在pom.xml文件中引入的依赖,其本身就需要依赖于其他的依赖,这时候我们不需要去考虑这些依赖,Maven会解析各个直接依赖的pom,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。

    通过传递性依赖,我们可以在pom.xml文件中少写不少的依赖配置

    传递性依赖的依赖范围
    假如当前项目为A,A依赖于B,B依赖于C。此时称A对于B是第一直接依赖,B对于C是第二直接依赖,而A对于C是传递性依赖。只要知道B在A项目中的scope,就可以知道C在A中的scope。其依赖范围如下:

    表格的第一列是B在A中的依赖范围,第一行是C在B中的依赖范围,交叉的格子是C在A中的依赖范围

    当C在B中的scope为test时,A不依赖C,C直接被丢弃
    当C在B中的scope为provided时,只有当B在A中的scope也是provided时,A才会依赖C,这时候C在A的scope是provided
    当C在B中的scope为compile或runtime时,A依赖C,此时C在A中的scope继承自B在A的scope。注意,如果C的scope是runtime,B的scope是compile,此时C在A的scope是runtime,而不是compile

    参考https://blog.csdn.net/u013704227/article/details/46460913

    https://blog.csdn.net/lewky_liu/article/details/78145211

  • 相关阅读:
    Python之面向对象新式类和经典类
    Python之面向对象继承和派生
    Python之面向对象类和对象
    Python之面向对象的程序设计
    Python之面向对象函数式编程
    Python之内置函数
    列表解析与生成器表达式
    03: 交换机基本原理与配置
    02: 网络布线与数制转换
    01:数据封装解封的过程
  • 原文地址:https://www.cnblogs.com/alice-cj/p/11442356.html
Copyright © 2011-2022 走看看