Maven 笔记 0x06:maven 的依赖

12 篇文章 0 订阅
12 篇文章 0 订阅

参考:

  • https://www.bilibili.com/video/BV1Fz4y167p5
  • https://www.runoob.com/maven/maven-pom.html


本文要解答的问题:

  • 依赖是什么
  • 依赖在哪配置
  • 一个依赖有哪些需要配置的点
  • 依赖范围
  • 依赖的传递性

依赖的概述

编写一个项目时,并非所有功能都要重新编写,可以复用一些别人写好的功能模块(jar 包)或插件,以节省项目的开发成本。这些别人写好的功能模块被引入到项目中,项目的很多功能都依赖于这些功能模块,这些功能模块(jar)就叫该项目的 “依赖”文件。

一个 Maven 项目的 “依赖” 是在该项目根目录下的 pom.xml 中配置的。

pom.xml 中根元素 <project> 下的 <dependencies> 可以包含多个 <dependency> 元素,一个 <dependency>声明一个依赖。

每个 dependency(依赖)都包含以下元素:

  1. <groupId><artifactId><version>:依赖的基本坐标。Maven 根据坐标才能找到该依赖。
  2. <type>:依赖的类型(如 jarwar),默认类型是 jar。它通常表示依赖文件的扩展名。大部分情况下不需要声明。
  3. <scope>依赖范围(compile、test、provided、runtime、system),在项目发布过程中,帮助决定哪些构件被包括进来。若不显式声明 <scope>的值,则取默认范围 compile,即编译、测试、运行都会去把这个 <dependency>包括进去。(在下面会详细讲这个 “依赖范围”)
  4. <optional>:标记依赖是否可选。如果你在项目 B 中把 C 依赖声明为可选,你就需要在依赖于 B 的项目(例如项目 A )中显式的引用对 C 的依赖。“可选依赖” 阻断依赖的传递性。
    <dependency>
        ...
        <optional>true</optional>
    </dependency>
    
  5. <exclusions>:用来排除传递性依赖。计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。此元素主要用于解决版本冲突问题。(在下面会详细讲 “依赖的传递性”)
    <dependency>
        ...
        <exclusions>
            <exclusion>
                <artifactId>spring-core</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    

依赖的适用范围(scope)

3 套 classpath

Maven 在对项目进行 编译、执行 测试、实际 运行 时会分别使用一套 classpath(即共 3 套 classpath)。

  • Maven 在编译项目主代码的时候,需要使用一套 classpath。比如:编译项目代码的时候需要用 spring-core,该文件以依赖的方式被引入到此 classpath 中。
  • Maven 在执行测试是会使用另一套 classpath。如:需引进 junit
  • Maven 在实际运行项目时,又会使用一套 classpath。此 classpath 需要引进 spring-core,但不需要引进 junit

依赖的适用范围 <scope>,就是描述 “该依赖” 与 3 套 classpath(编译/默认classpath、测试classpath、运行时classpath)的关系。

scope

如果没有显式指定 <scope> 的值,则 <scope>取默认值compile

  • Compile:“默认(编译)范围”,指此依赖会被 3 套 classpath(编译、测试、运行时)引用。
  • test:“测试范围”。指此依赖只会被 “测试 classpath” 引用。编译、运行时的 classpath 无法引用此依赖。
    • 例:junit 的 <scope> 就是指定为 test
  • runtime:“运行时范围”。指此依赖会被 “测试 classpath” 与 “运行时 classpath” 引用,但不被 “编译 classpath” 引用。
    • 例:jdbc 驱动程序,项目主代码的编译只需要 jdk 提供的 jdbc 接口,只有在执行测试或运行项目时,才需要实现上述接口的具体 jdbc 驱动程序。
  • provided:“已提供范围”。指此依赖会被 “编译 classpath” 与 “测试 classpath” 引用,但不被 “运行时 classpath” 引用。
    • 例:servlet-api,编译和测试项目时需要该依赖。但在运行项目时,由于容器已经提供,就不需要 Maven 重复地引入一遍。
  • system:“系统范围”。和 provided 的依赖适用范围一致,但使用 system 系统范围时,必须通过 systemPath 元素显式地指定依赖文件的路径。
    • 另外,由于此类依赖不是通过 Maven 仓库解析的,往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。
编译 classpath测试 classpath运行时 classpath依赖案例
compile(或缺省)vvv
testvjunit
runtimevvjdbc 驱动程序
providedvvservlet-api
systemvv一般不使用
<dependency>
    <scope>test</scope>
</dependency>

传递性依赖

传递依赖机制,让我们在使用某个 jar 包的时候,不用去考虑它依赖了什么,也不用担心引入多余的依赖。Maven 会解析各个直接依赖的 POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目。

比如:A 依赖于 B,B 又依赖于 C。就会形成传递性依赖 A --> B --> C,那么,编译运行项目 A 时,Maven 就会不单把 B 包括进来,也会把 C 包括进来。

传递依赖产生冲突

传递依赖有可能产生冲突。

比如:

A --> B --> C(C 的 2.0 版本)
A --> E --> C(C 的 1.0 版本)

也就是说 A 同时依赖了 C 的两种版本,这就是所谓的 “冲突”。此时就需要使用到上面提到过的 <exclusions> 标签,来排除传递性依赖造成的冲突。

<dependencies> 
    <dependency> 
        <groupId>A</groupId> 
        <artifactId>A</artifactId> 
        <version>xxx</version> 
        <exclusions>                        <----
            <exclusion>                     <==== 这样就会去处理 C 的版本冲突,选取同时适合 A、B 的 C 的版本
                <groupId>C</groupId> 
                <artifactId>C</artifactId>
            </exclusion> 
        </exclusions>                       <----
    </dependency>
    
    <dependency> 
        <groupId>B</groupId> 
        <artifactId>B</artifactId> 
    </dependency> 
</dependencies>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
找了很久 的 终于搞好了 JSON数据以来包全部的jar包 解压后放在项目下就可以了 下面付源代码 import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class Json { public static void main(String[] args) { Json j = new Json(); j.bean2json(); } public void arr2json() { boolean[] boolArray = new boolean[] { true, false, true }; JSONArray jsonArray = JSONArray.fromObject(boolArray); System.out.println(jsonArray); // prints [true,false,true] } public void list2json() { List list = new ArrayList(); list.add("first"); list.add("second"); JSONArray jsonArray = JSONArray.fromObject(list); System.out.println(jsonArray); // prints ["first","second"] } public void createJson() { JSONArray jsonArray = JSONArray.fromObject("['json','is','easy']"); System.out.println(jsonArray); // prints ["json","is","easy"] } public void map2json() { Map map.put("name", "json"); map.put("bool", Boolean.TRUE); map.put("int", new Integer(1)); map.put("arr", new String[] { "a", "b" }); map.put("func", "function(i){ return this.arr[i]; }"); JSONObject json = JSONObject.fromObject(map); System.out.println(json); // prints // ["name":"json","bool":true,"int":1,"arr":["a","b"],"func":function(i){ // return this.arr[i]; }] } public void bean2json() { JSONObject jsonObject = JSONObject.fromObject(new MyBean()); System.out.println(jsonObject); } public void json2bean() { String json = "{name=\"json2\",func1:true,pojoId:1,func2:function(a){ return a; },options:['1','2']}"; JSONObject jb = JSONObject.fromString(json); JSONObject.toBean(jb, MyBean.class); System.out.println(); } } 操作的bean: import net.sf.json.JSONFunction; public class MyBean { private String name = "json"; private int pojoId = 1; // private char[] options = new char[] { 'a', 'f' }; private String func1 = "function(i){ return this.options[i]; }"; private JSONFunction func2 = new JSONFunction(new String[] { "i" }, "return this.options[i];"); // getters & setters ...... }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值