maven 常用知识速记

news2025/1/10 20:59:06

创建项目

maven archetype:generate

依赖范围

有如下依赖示例:

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

其中有一个scope标签来声明该依赖的作用范围
首先需要知道,Maven 在编译项目主代码的时候需要使用一套 classpath。在上例中,假如编译项目主代码的时候需要用到 spring-core, 该文件以依赖的方式被引入到 classpath 中。其次,Maven 在编译和执行测试的时候会使用另外一套 classpath。上例中的 JUnit 就是个很好的例子,该文件也以依赖的方式引入到测试使用的 classpath 中,不同的是这里的依赖范围是 test。最后,实际运行 Maven 项目的时候,又会使用一套 classpath, 上例中的 spring-core 需要在该 classpath 中,而 JUnit 则不需要。 依赖范围就是用来控制依赖与这三种 classpath(编译 classpath、测试 classpath、运行 classpath) 的关系,Maven 有以下几种依赖范围:

  • compile: 编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的 Maven 依赖,对于编译、测试、运行三种 classpath 都有效。典型的例子是 spring-core, 在编译、测试和运行的时候都需要使用该依赖。

  • test: 测试依赖范围。使用此依赖范围的 Maven 依赖,只对于测试 classpath 有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子是 JUnit, 它只有在编译测试代码及运行测试的时候才需要。

  • provided: 已提供依赖范围。使用此依赖范围的 Maven 依赖,对于编译和测试 class-path 有效,但在运行时无效。典型的例子是 servlet-api, 编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要 Maven 重复地引入一遍

  • runtime: 运行时依赖范围。使用此依赖范围的 Maven 依赖,对于测试和运行 class-path 有效,但在编译主代码时无效。典型的例子是 JDBC 驱动实现,项目主代码的编译只需要 JDK 提供的 JDBC 接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体 JDBC 驱动。

  • system: 系统依赖范围。该依赖与三种 classpath 的关系,和 provided 依赖范围完全一致。但是,使用 system 范围的依赖时必须通过 systemPath 元素显式地指定依赖文件 的路径。由于此类依赖不是通过 Maven 仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。 systemPath 元素可以引用环境变量,如:

<dependency>
    <groupId>javax.sql</groupId>
    <artifactId>jdbc-stdex</artifactId>
    <version>2.0</version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
  • import(Maven2.0.9 及以上):导入依赖范围。该依赖范围不会对三种 classpath 产生实际的影响。

传递性依赖和依赖调解

Maven 会解析各个直接依赖的 POM, 将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。

但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。 例如,项目 A 有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0),X 是 A 的传递性依赖,但是两条依赖路径上有两个版本的 X, 那么哪个 X 会被 Maven 解析使用呢? 两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择-一个。

依赖调解

Maven 依赖调解 (Dependency Mediation) 的第一原则是:
路径最近者优先 :
该例中 X(1.0) 的路径长 度为 3,而 X(2.0) 的路径长度为 2,因此 X(2.0) 会被解析使用。

如果路径长度一致,那么使用第二原则:
第一声明者优先
比如这样的依赖关系:A->B->Y(1.0)、A-> C->Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。
依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前 的那个依赖优胜。该例中,如果B的依赖声明在C之前,那么Y(1.0)就会被解析使用

依赖管理

查看依赖

maven dependency:list

依赖树

maven dependency:tree

依赖分析

列出使用但为直接声明的依赖,以及声明但未使用的依赖

maven dependency:tree

该结果中重要的是两个部分。首先是 Used undeclared dependencies, 意指项目中使用到的,但是没有显式声明的依赖,这里是 jackson-core:jar. 这种依赖意味着潜在的风险,当前项目直接在使用它们,例如有很多相关的 Java import 声明,而这种依赖是通过直接依赖传递进来的,当升级直接依赖的时候,相关传递性依赖的版本也可能发生变化这种变化不易察觉,但是有可能导致当前项日出错。例如由于接口的改变,当前项目中的相关代码无法编译。这种隐藏的、潜在的威胁一旦出现,就往往需要耗费大量的时间来查明真相。因此,显式声明任何项目中直接用到的依赖

结果中还有一个重要的部分是 Unused declared dependencies, 意指项目中未使用的,但显式声明的依赖,这里有 jna-platform:jar。需要注意的是,对于这样一类依赖,我们不应该简单地直接删除其声明,而是应该仔细分析。由于 dependency:analyze 只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它就发现不了。

归类依赖

有很多关于 Spring Framework 的依赖,例如 org.springframework:spring-core:2.5.6,org.springframeworkspring-beans:2.5.6,org.springframework:spring-context:2.5.6org.springframework:spring-context-support:2.5.6, 它们是来自同一项目的不同模块。 因此,所有这些依赖的版本都是相同的,而且可以预见,如果将来需要升级 Spring Frame-work, 这些依赖的版本会一起升级。

对于项目中的这些 Spring Framework 来说,也应该在一个唯一的地方定义版本,并且在 dependency 声明中引用这一版本。这样,在升级 Spring Framework 的时候就只 需要修改一处。

例子:

<project>
    <modelversion>4.0.0</modelversion>
    <groupId>com.juven.mvnbook.account</groupId>
    <artifactId>account-email</artifactId>
    <name>Account Email</name>
    <version>1.0.0-SNAPSHOT</version>
    <!--定义属性-->
    <properties>
        <springframework.version>2.5.6</springframework.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <!--使用属性-->
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
    </dependencies>
</project>

联系方式:dccmmtop@foxmail.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1100253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中用序列化和反序列化来保存游戏进度

[System.Serializable]标记类 序列化 [System.Serializable]是一个C#语言中的属性&#xff0c;用于标记类&#xff0c;表示该类的实例可以被序列化和反序列化。序列化是指将对象转换为字节流的过程&#xff0c;以便可以将其保存到文件、数据库或通过网络传输。反序列化则是将字…

Davinci NvM Block配置

存储块的配置方法 在下图中的位置添加Block的时候&#xff0c;Davinci会在NVM模块和Fee模块同时添加Block&#xff0c;并进行关联。且Fee Block的数量由NvM Block的类型决定&#xff0c;当NvM Block是Native时&#xff0c;会生成一个Fee Block&#xff1b;当NvM Block是Redund…

ant design vue:自定义锚点样式

要做一个如下图的锚点&#xff0c;ant design vue的锚点样式比较简单&#xff0c;按照官网文档:affix"false" :showInkInFixed"true"&#xff0c;就可以显示小方块&#xff0c;但是我试了一下不管用&#xff0c;而且锚点组件不固定起来很不方便&#xff0c…

[大三上20231016]JavaEE SpringBoot

[大三上20231016]JavaEE SpringBoot 学习是个积累,踏踏实实去做,多去虚心请教,热爱兴趣很重要 课前提问: Spring框架中的核心组件是什么? IOC,AOP IOC: Inversion of Control即控制反转 AOP: Aspect Oriented Programming 面向切面编程 什么是IOS什么是DI? IOS(作用:…

《向量数据库指南》——选择向量数据库时需要考量的点Milvus Cloud

大禹智库:选择向量数据库时需要考量的点 性能 如上述,查询性能(查询的响应时间,系统的吞吐能力)是在选型向量数据库时的一个重要参考点,市面上现有的向量数据库的 Benchmark 有: ANN-Benchmark 是一种用于评估各种向量数据库和近似最近邻(ANN)算法性能的工具 VectorD…

如何快速集成讯飞星火 2.0 API ?

大家好&#xff0c;我是二哥呀。 之前带大家体验了两波科大讯飞的星火认知大模型&#xff0c;真没想到&#xff0c;反馈远超我的预期&#xff0c;大家普遍都说好&#xff0c;不仅注册方便&#xff0c;工作和学习的效率也得到了极大的提升。 今天继续给大家带来重磅体验&#…

SLAM从入门到精通(a*搜路算法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前机器人常用的搜路算法主要有这么几种&#xff0c;迪杰斯特拉算法、a*算法、贪心算法。每一种算法都有自己的场景和优势&#xff0c;可以灵活选…

如何在Linux环境中远程访问企业级夜莺监控分析工具?

文章目录 前言1. Linux 部署Nightingale2. 本地访问测试3. Linux 安装cpolar4. 配置Nightingale公网访问地址5. 公网远程访问Nightingale管理界面6. 固定Nightingale公网地址 前言 夜莺监控是一款开源云原生观测分析工具&#xff0c;采用 All-in-One 的设计理念&#xff0c;集…

微信小程序2

一&#xff0c;视图层 1.什么视图层 框架的视图层由 WXML 与 WXSS 编写&#xff0c;由组件来进行展示。 将逻辑层的数据反映成视图&#xff0c;同时将视图层的事件发送给逻辑层。 WXML(WeiXin Markup language) 用于描述页面的结构。 WXS(WeiXin Script) 是小程序的一套脚本语…

深入理解强化学习——强化学习智能体的四要素:策略(Policy)

分类目录&#xff1a;《深入理解强化学习》总目录 相关文章&#xff1a; 强化学习智能体的四要素&#xff1a;策略&#xff08;Policy&#xff09; 强化学习智能体的四要素&#xff1a;收益信号&#xff08;Revenue Signal&#xff09; 强化学习智能体的四要素&#xff1a;价…

备忘录模式-撤销功能的实现

在idea写代码的过程中&#xff0c;会经常用到一个快捷键——“crtl z”,即撤销功能。“备忘录模式”则为撤销功能提供了一个设计方案。 1 备忘录模式 备忘录模式提供一种状态恢复机制。在不破坏封装的前提下&#xff0c;捕获对象内部状态并在该对象之外保存这个状态。可以在…

关于职业规划的学习经验总结

目录 前言 结构化思考 思考快与慢 积极主动 以终为始 要事第一 前言 每一年的年中或者年终都有一场很重要的活动就是述职,需要花费一定精力投入,那么述职是一种形式吗?当然不是。述职是一种组织的管理手段和机制,通过这种机制除了对战略方向和项目进度进行把控,还对…

chatgpt 4V 识图功能

1.获取图片的sig和file_id 2e0edc6e489ed13a3f32f0dd87527d77.jpg是本地图片的名字 头部认证信息自己F12 抓取 1.获取图片的sighttps://chat.openai.com/backend-api/filesAuthorization:Bearer eyJhbGc****************5V-lztYwLb9hr6LP7g Cookie: **********************…

set_data_check做等长线

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 常常会遇见2out的多个信号需要做等长&#xff0c;下面分享一个脚本。 set port1_coll [get_ports out[*]] set port2_coll [get_ports out[*]] foreach_in_collection temp1 $…

ChatGPT教你5分钟解锁国际象棋技能

国际象棋是一种很好玩的棋类游戏&#xff0c;走法和规则与中国象棋有所区别。如果想要快速入门&#xff0c;可以把ChatGPT当做私人教练&#xff0c;提出这些问题&#xff1a; ●作为零基础的初学者&#xff0c;学习国际象棋的最佳方法是什么&#xff1f;如何快速入门&#xff…

计算机保研推免面试复习大纲(数学+408)

目录 线性代数概率论高等数学信号与系统离散数学操作系统计算机网络计算机组成数据结构算法编译原理C杂项 线性代数 怎么求逆矩阵 逆矩阵&#xff1a; A A − 1 E AA^{-1}E AA−1E&#xff0c;伴随矩阵&#xff1a; A A ∗ A ∗ A ∣ A ∣ E AA^{*}A^{*}A|A|E AA∗A∗A∣A∣…

算法通关村第一关-链表白银经典问题笔记

大家好今天来写第一关的白银挑战-链表经典问题. 两个链表的第一个公共结点 这是一道经典的链表问题 : 输入两个无环的单向链表&#xff0c;找出它们的第一个公共结点&#xff0c;如果没有公共节点则返回空。 牛客NC66 : 剑指offer56 : 分析 : 屡试不爽的方法: 将常用数据…

第15章 SpringBoot

所有的流程逻辑原理都是针对2.3.2.RELEASE版本 15.1 谈谈你对微服务架构演进的理解 难度:★ 重点:★ 白话解析 还是串主线,在串主线的过程中发现问题,解决问题。主线的入口:随着业务的逻辑越来越复杂,架构再不断升级演进,先理解架构的演进。 这道题参考了:企业IT架构转…

引领虚拟化技术新潮流:VMware Fusion Pro for Mac/win中文版

当谈论虚拟机时&#xff0c;很多人可能会对其有所了解&#xff0c;但并不一定清楚它的具体作用和优势。在这篇文章中&#xff0c;我们将带您走进虚拟机的世界&#xff0c;并深入了解VMware Fusion Pro这一专业虚拟化解决方案的独特魅力。 虚拟机是一种模拟真实计算机环境的软件…