zoukankan      html  css  js  c++  java
  • 读书笔记-《Maven实战》-关于Maven依赖传递的思考 2018/4/26

    上次读书笔记中,提到了依赖传递。看着依赖传递表,一直在思考为什么会是这样。

    先看传递表:

    compile test provided runtime

    compile

    test

    provided

    runtime

    compile

    test

    provided

    runtime

    -

    -

    -

    -

    -

    -

    -

    -

    runtime

    test

    provided

    runtime

    (最左边一列表示第一依赖范围,最上边一行表示第二依赖范围)

    需要详细理解的知识点

    1.首先看看scope的作用:scope是用来排除多余的依赖范围的。按我自己的理解,不能理解一个字段在什么时候有用,而是在什么时候不需要它,在什么时候,添加了这个范围就会出现操作失败的情况: 

    compile:所有阶段都有用,

    provided:在运行的时候不需要使用这个依赖,更官方的说法为期望在运行时由运行环境提供api。

    test:在编译和运行的时候都不要使用这个依赖【具体理解应该是在正式的使用mvn package或者mvn compile的时候无效,但是对于编译器来说,是一直有效的,因为测试也需要编译和运行的】

    runtime:对于编译的时候不需要使用这个依赖【例:JDBC驱动,在编译的时候只需要提供一个接口,具体使用在运行的时候再提供就行】

    理解记忆的话:

    test算是一个独立的模块。如果对于上面的依赖传递表格不理解的话,可以先把test行和test列给去除,再结合2,3知识点,就很容易理解了

    priovided和runtime是对立的,一个对运行时不需要,一个对编译时不需要。 参考理解jdk和jre

    2.编译时和运行时具体区别在哪里?

    具体的可以看看《深入理解JVM》

    只说一点关键的:

    编译过程中,对于依赖,可以没有具体的实现,但是需要有这个接口文件,不需要有具体的实现。[可以只有interface文件]

    运行过程中,对于依赖,必须要有具体的实现。[还要有具体的implement文件]

    3.依赖是指的依赖编译好的二进制文件,编译过程会把所有的依赖编译进生成的二进制文件中,这一点很重要

    而依赖是否传递,主要看是否需要运行或编译文件,与test无关

    因此:

    先看看第一依赖为compile的时候:(运行和编译都需要此依赖)

    第二依赖对库的依赖为compile的时候:

    表示任何时候都需要这个lib,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此

    现在的库对于第二依赖在编译的时候,不需要再编译一次,因此应该是在运行时和测试时有效,所以应该为runtime,但是官方解释:

    it is intended that this should be runtime scope instead, so that all compile dependencies must be explicitly listed - however, there is the case where the library you depend on extends a class from another library, forcing you to have available at compile time. For this reason, compile time dependencies remain as compile scope even when they are transitive.

     

    第二依赖对库的依赖为test的时候:

    第二依赖的运行和编译都不需要这个库,因此,依赖是不会传递的

    第二依赖对库的依赖为provided的时候:

    第二依赖在运行时不需要这个库,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此编译运行都不需要这个库,因此,依赖不会传递

    第二依赖对库的依赖为runtime的时候:

    第二依赖在编译的时候不需要这个库,但是在运行和测试的时候需要这个库,那么同理第一依赖编译的时候是不需要这个库的。因此为runtime。

    第一依赖为test的时候:(运行和编译都需要此库)

    第二依赖对库的依赖为compile的时候:

    第一依赖只需要用第二依赖进行测试,第二依赖对这个依赖任何时候都需要(其实只需要再运行的时候用它,因为已经被编译到二进制文件中了),因此在只需要在测试的时候,运行这个包,因此为test

     

    第二依赖对库的依赖为test的时候:

    第一依赖只需要用第二依赖进行测试,第二依赖运行和编译的时候都不需要他,因为依赖不传递

     

    第二依赖对库的依赖为provided的时候:

    第一依赖对第二依赖进行测试,第二依赖在运行的时候不需要这个这个库,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此依赖不传递。

     

    第二依赖对库的依赖为runtime的时候:

    第二依赖在编译的时候不需要这个库,而在运行和测试的时候需要这个库,而在测试的时候需要运行这个库,因此为test

    可以看出来compile和test很像,在proivde和test都不传递。而在compile和runtime都会传递,因为proivde对于被依赖项来说已经编译好了,所以不再需要传递

    第一依赖为provided的时候:(在编译和运行测试代码的时候需要此库)

    provided算是一个比较特殊的依赖。需要注意的是,我们的代码并不是在运行时不需要这个库,而是表示在运行时让运行环境提供这个api。

    因此如果按照表示主代码在运行时让运行环境提供这个依赖的运行api,那么在第一依赖需要运行第二依赖的时候,依赖都为provided

     

    第二依赖为compile的时候:(运行和编译都需要此库)

    按照上面的说法,应该为provided

     

    第二依赖对库的依赖为test的时候:

    第一依赖只需要用第二依赖进行测试,第二依赖运行和编译的时候都不需要他,因为依赖不传递

     

    第二依赖对库的依赖为provided的时候:

    第一依赖对第二依赖进行测试,第二依赖在运行的时候不需要这个这个库,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此依赖不传递。

     

    第二依赖对库的依赖为runtime的时候:

    第二依赖在运行的时候需要这个库,因此为provided

    第一依赖为runtime的时候:(在运行的时候需要此库)

    第二依赖为compile的时候:(运行和编译都需要此库)

    表示任何时候都需要这个lib,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此

    现在的库对于第二依赖在编译的时候,不需要再编译一次,因此应该是在运行时和测试时有效,因此为runtime

     

    第二依赖对库的依赖为test的时候:

    第一依赖只需要用第二依赖进行测试,第二依赖运行和编译的时候都不需要他,因为依赖不传递

     

    第二依赖对库的依赖为provided的时候:

    第一依赖对第二依赖进行测试,第二依赖在运行的时候不需要这个这个库,而编译的时候这个lib已近被第二依赖编译进二进制文件,因此依赖不传递。

     

    第二依赖对库的依赖为runtime的时候:

    第二依赖在编译的时候不需要这个库,而在运行和测试的时候需要这个库,因此为runtime

  • 相关阅读:
    备忘录模式
    中介者模式
    观察者模式、发布订阅和事件驱动
    ELK日志系统之kibana的使用操作
    ELK日志系统之说说logstash的各种配置
    03篇ELK日志系统——升级版集群之ELK日志系统整合springboot项目
    02篇ELK日志系统——升级版集群之kibana和logstash的搭建整合
    01篇ELK日志系统——升级版集群之elasticsearch集群的搭建
    Linux安装jdk环境
    01GitLab的使用——创建项目并上传到GitLab
  • 原文地址:https://www.cnblogs.com/dengchengchao/p/8952890.html
Copyright © 2011-2022 走看看