maven 常用知识速记

创建项目

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.rhkb.cn/news/164906.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

18.项目开发之前端项目搭建测试

项目开发之前端项目搭建测试 解压文件&#xff0c;将前端项目目录&#xff0c;拖拽到HBuilder中 前端项目QuantTrade_vue地址&#xff1a;传送门 后端项目QuantTrade地址&#xff1a; https://pan.baidu.com/s/1GF45B0QepApH8JbRIOLY7w?pwd1016 开启idea的项目&#xff0c;先…

一个适合练手的接口测试实战项目——慕慕生鲜

前言 最近很多粉丝找小月要接口测试项目练练手&#xff0c;看看实力&#xff01;今天&#xff0c;它来了 慕慕生鲜&#xff0c;完整版&#xff0c;文末有福利&#xff01; 干货来咯&#xff0c;收藏好&#xff01; 1. 接口测试需求分析 常见接口文档提供的两种方式 ①wor…

四川竹哲电商:抖店怎么修改经营类目?

抖店是抖音推出的一款电商工具&#xff0c;通过抖店可以帮助商家在抖音上开展经营活动。在抖店平台上&#xff0c;商家需要选择经营类目&#xff0c;以便在相应的领域展示商品和提供服务。然而&#xff0c;有时候商家可能需要修改经营类目&#xff0c;以适应经营策略调整或扩大…

Linux进程(三)--进程切换命令行参数

继上回书Linux进程概念&#xff08;二&#xff09;--进程状态&进程优先级&#xff0c;我们在了解了Linux进程状态和优先级的概念&#xff0c;初步掌握了进程状态的相关知识&#xff0c;最终&#xff0c;我们以Linux进程的优先级&#xff0c;引出了一些其他的概念&#xff1…

Python---循环---while循环

Python中的循环 包括 while循环与for循环&#xff0c;本文以while循环为主。 Python中所有的知识点&#xff0c;都是为了解决某个问题诞生的&#xff0c;就好比中文的汉字&#xff0c;每个汉字都是为了解决某种意思表达而诞生的。 1、什么是循环 现实生活中&#xff0c;也有…

(N-128)基于springboot,vue酒店管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis 本系统功…

vueday02——使用NTableData

1.下载naivueui 2.按需导入&#xff0c;不要全局导入 注意不要导入错误组件或者写错组件名称 import { NDataTable } from naive-ui 3.定义表头和数据&#xff01;&#xff01;&#xff01; n-data-table标签必须要使用数据和数据 少一个都不能正确渲染&#xff01;&#xf…

ATA-M4功率放大器都有哪些具体特点及优势

我们的ATA-M系列功率放大器&#xff0c;旨在将它打造为超越ATA-L系列水声功率放大器高频限制的系列产品。其中ATA-M4功率放大器是一款理想的单通道功率放大器。最大输出345Vrms电压&#xff0c;400VA功率&#xff0c;可驱动0~100%的阻性或非阻性负载。输出阻抗匹配多个档位可选…

GCC优化相关

文章目录 优化选项博文链接 单独设置某段代码优化等级博文链接 优化选项 -O/-O0:无优化(默认)-O1:使用能减少目标文件大小以及执行时间并且不会使编译时间明显增加的优化。该模式在编译大型程序的时候会花费更多的时间和内存。在-O1 下&#xff0c;编译会尝试减少代码体积和代码…

内核初始化的过程

内核的启动从入口函数 start_kernel() 开始。在 init/main.c 文件中&#xff0c;start_kernel 相当于内核的 main 函数。打开这个函数&#xff0c;你会发现&#xff0c;里面是各种各样初始化函数 XXXX_init。 在操作系统里面&#xff0c;先要有个创始进程&#xff0c;有一行指令…

JAVA发送消息到RabbitMq

项目中&#xff0c;作为生产者自定义消息发送到RabbitMq。 1.引入rmq依赖 <!-- rabbitmq 依赖 --><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.9.0</version></dependen…

SystemVerilog Assertions应用指南 Chapter1.31 在属性中使用形参

可以用定义形参( formal arguments)的方式来重用一些常用的属性。属性“arb”使用了4个形参,并且根据这些形参进行检验。其中还定义了特定的时钟。SVA允许使用属性的形参来定义时钟。这样,属性可以应用在使用不同时钟的相似设计模块中。同样的,时序延迟也可以参数化,这使得属性…

cocos creator 在网页中调试的时候直接代码调试方法

cocos creator 在网页中调试的时候直接代码调试方法

Milvus 介绍

Milvus 介绍 Milvus 矢量数据库是什么&#xff1f;关键概念非结构化数据嵌入向量向量相似度搜索 为什么是 Milvus?支持哪些索引和指标&#xff1f;索引类型相似度指标(Similarity metrics) 应用示例Milvus 是如何设计的&#xff1f;开发者工具API访问Milvus 生态系统工具 本页…

算法专题:双指针

目录 题目1&#xff1a;移动零 题目2&#xff1a;复写零 题目3&#xff1a;快乐数 题目4&#xff1a;最多水的容器 题目5&#xff1a;有效三角形的个数 题目6&#xff1a;两数之和为s 题目1&#xff1a;移动零 给定一个数组nums&#xff0c;编写一个函数将所有的0移动到数…

VueRouter 源码解析

重要函数思维导图 路由注册 在开始之前&#xff0c;推荐大家 clone 一份源码对照着看。因为篇幅较长&#xff0c;函数间的跳转也很多。 使用路由之前&#xff0c;需要调用 Vue.use(VueRouter)&#xff0c;这是因为让插件可以使用 Vue export function initUse(Vue: GlobalAP…

Vue2使用定时器和闭包实现防抖和节流函数。将函数放入util.js中,供具体功能在methods中调用

Vue2使用定时器和闭包实现防抖和节流函数。将函数放入util.js中&#xff0c;供具体功能在methods中调用。<br/ 参考文档&#xff1a; 如何在Vue中优雅的使用防抖节流人类高质量JS防抖与节流机制Vue项目中使用防抖和节流vue2使用lodash中的防抖&#xff08;debounce&#xff…

Android端自定义铃声

随着移动应用竞争进入红海时代&#xff0c;如何在APP推送中别出心裁显得尤为重要。例如对自己的APP推送赋予独特的推送铃声&#xff0c;能够给用户更加理想的使用体验。 1、个性化提醒铃声有助于当收到特定类型的消息时&#xff0c;用户能够立刻识别出来。 2、不同的推送铃声…

性能测试的分类、区别以及特点这些你都知道了吗?

现在性能测试一个比较火的话题&#xff0c;究其原因是因为现在很多公司都要求测试人员会做性能测试&#xff0c;所以今天小编就来普及下性能测试的几种分类和其特点。 关于性能测试有几个名词&#xff1a;性能测试、负载测试、压力测试、并发测试&#xff0c;很多人都是混合使…

零基础制作预约小程序,微信小程序预约服务指南

随着互联网的发展&#xff0c;越来越多的服务开始转移到线上。预约服务也是其中之一。通过微信小程序&#xff0c;商家可以提供更加便捷的预约服务&#xff0c;让客户随时随地预约商品或服务。本文将介绍如何零基础制作预约小程序&#xff0c;包括使用第三方制作平台、选择合适…