Gradle学习笔记之依赖

news2024/9/28 3:18:54

文章目录

  • 依赖的方式
    • 直接依赖
    • 项目依赖
    • 本地jar包依赖
  • 依赖的类型
  • api和implementation的区别
  • 依赖冲突及解决方案
    • 移除某个依赖
    • 不允许依赖传递
    • 强制使用某个版本
    • 依赖冲突时立刻构建失败

依赖的方式

Gradle中的依赖方式有直接依赖、项目依赖和本地jar包依赖三种:

dependencies {
    // 1、依赖当前项目下的某个模块[子工程]
    implementation project(':subject01')
    // 2、直接依赖本地的某个jar文件
    implementation files('libs/foo.jar', 'libs/bar.jar')
    // 2、配置某文件夹作为依赖项
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 3、直接依赖
    implementation 'org.apache.logging.log4j:log4j:2.17.2'
}

直接依赖

在项目中直接导入的依赖,即为直接依赖,如:

    implementation 'org.apache.logging.log4j:log4j:2.17.2'

完整写法如下,其中group/name/version共同定位一个远程jar包:

    implementation group: 'org.apache.logging.log4j', name: 'log4j;, version: '2.17.2'

项目依赖

依赖项目中的另一个模块,被依赖的模块需要是library模块,并且在settings.gradle中配置:

    implementation project(':subject01')

本地jar包依赖

即依赖本地jar包,有如下两种方式:

    // 2、直接依赖本地的某个jar文件
    implementation files('libs/foo.jar', 'libs/bar.jar')
    // 2、配置某文件夹作为依赖项
    implementation fileTree(dir: 'libs', include: ['*.jar'])

依赖的类型

在这里插入图片描述
其中java插件的功能,java-library插件都提供。

api和implementation的区别

如下表所示:

apiimplementation
编译时能进行依赖传递;底层变,上层全部都要变;编译速度慢不能进行依赖传递;底层变,上层不会变化;编译速度快
运行时运行时会加载,所有模块的类都会被加载运行时会加载,所有模块的类都会被加载
应用场景适用于多模块依赖,避免重复依赖多数情况下使用implementation

以下图为例:
在这里插入图片描述
libC发生变化时,libAprojectX也随之变化,都需要重新编译;当libD发生变化时,直接依赖它的libB随之变化,而没有直接依赖libDprojectX不会发生变化,也只有libDlibB要重新编译。

再考虑一种场景:一个工程中,moduleA依赖moduleBmoduleCmoduleB也依赖moduleC,因此可以让moduleBapi的方式依赖moduleCmoduleA则只implementation依赖moduleB即可。

再例如,一个工程中有ABCD四个模块:
1)、A implmentation B,B implementation C,则A不可用C;
2)、A implmentation B,B api C,则A可用C;
3)、A implmentation B,B implementation C,C api D,则B可用D,A不可用D;
4)、A implmentation B,B api C,C api D,则A可用D。

任何情况下,发生依赖的模块里所有的类都会被加载。

依赖冲突及解决方案

依赖冲突是指,在编译过程中,若存在对某个包的多版本依赖,构建系统要选择哪个进行构建,如下图所示:
在这里插入图片描述
其中,ABC都是本地项目或模块,log4j时远程依赖。编译时,BC各用各的log4j,彼此没有冲突。但打包时,只能有一个版本的代码被打到jar包中,因此就发生了冲突。

事实上,gradle默认会选择最新的版本去打包,因为新版本的jar包一般都是向下兼容的,因此推荐这种官方的默认解决方法,不过gradle也提供了一系列的解决依赖冲突的方法:移除某个依赖;不允许依赖传递或强制使用某个版本。

移除某个依赖

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

    implementation('org.hibernate:hibernate-core:3.6.3.Final'){
        // 排除某一个库(slf4j)依赖:如下三种写法都行
        exclude group: 'org.slf4j'
        exclude module: 'slf4j-api'
        exclude group: 'org.slf4j',module: 'slf4j-api'
    
    // 排除之后,使用手动的引入即可。
    implementation 'org.slf4j:slf4j-api:1.4.0'
}

不允许依赖传递

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
    implementation('org.hibernate:hibernate-core:3.6.3.Final'){
        // 不允许依赖传递,一般不用
        transitive(false)
    }
    // 排除之后,使用手动的引入即可
    implementation 'org.slf4j:slf4j-api:1.4.0'
}

不允许依赖传递,则该依赖的所有内部依赖均不会添加到编译或运行时的类路径中,

强制使用某个版本

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
    implementation('org.hibernate:hibernate-core:3.6.3.Final')
    // 强制使用某个版本【官方建议使用这种方式】
    implementation('org.slf4j:slf4j-api:1.4.0!!')
    // 这种效果和上面那种一样,强制指定某个版本
    implementation('org.slf4j:slf4j-api:1.4.0'){
        version{
            strictly("1.4.0")
        }
    }
}

依赖冲突时立刻构建失败

事实上,我们可以配置当Gradle遇到依赖冲突时,立刻构建失败,从而找出项目或模块中的所有的依赖冲突:

// 项目或模块的build.gradle

configurations.all {
    Configuration config -> {
        // 当遇到版本冲突时直接构建失败
        config.resolutionStrategy.failOnVersionConflict()
    }
}

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

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

相关文章

【一起从0开始学习人工智能0x02】字典特征抽取、文本特征抽取、中文文本特征抽取

注:最后有面试挑战,看看自己掌握了吗 文章目录什么是特征工程?用什么做?1.特征提取特征值化:特征提取API字典特征提取---向量化---类别--》one-hot编码哑变量one-hot-------直接1234会产生歧义,不公平应用场…

Python 10k+ 面试试题,看看你是否掌握

前言 大家早好、午好、晚好吖 ❤ ~ 面试实战题:采集世界最大旅游平台Tripadvisor 另我给大家准备了一些资料,包括: 2022最新Python视频教程、Python电子书10个G (涵盖基础、爬虫、数据分析、web开发、机器学习、人工智能、面试题&#xff…

Python GUI编程:音乐播放器(多线程、爬虫、进度条、文件)

文章目录1. 程序运行结果2.程序实现原理3. GUI布局4. 功能介绍5. 代码实现1. 程序运行结果 Python实现音乐播放器(爬虫、多线程、进度条、文件)2.程序实现原理 本音乐播放器GUI方面运用Python的tkinter实现,播放的音乐来自网络爬虫和本电脑已经有的。为了使整个程序…

Android studio设置全屏显示的两种方式

两种在Androidstudio中设置全屏的方式,推荐第二种 第一种(Java文件中设置) 直接在onCreate()函数中设置 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);package com.exa…

MARKETS AND MARKET LOGIC——The Market‘s Principles (6)_3

市场的组成——对行为观察的反思 制定市场理解 理解市场逻辑将有助于每个参与者提高其在市场上成功的可能性,因为他将能够阅读市场活动并接收市场生成的信息,这些信息很少有参与者承认或理解。这一信息特别涉及市场如何接受或拒绝随着时间的推移而升高或…

Linux用户标识符UID与GID和用户账号

1.用户标识符UID和GID UID 表示的是用户的标识(User Identification) GID 表示的是用户组的标识(Group Identification) 显示用户ID信息。 命令:id username 2.用户账号 用户和用户组的信息都存放在…

RabbitMQ(一)Windows下载安装

目录一、下载安装包二、安装erlang三、安装RabbitMQ四、配置RabbitMQ管理界面官网地址:https://www.rabbitmq.com/ 下载地址:https://www.rabbitmq.com/download.html 一、下载安装包 RabbitMQ Windows下载地址:https://www.rabbitmq.com/in…

001. Nginx场景,优点,组成部分和编译

目录一: Nginx三个重要的使用场景二: Nginx的优点三:Nginx文件的组成部分四:编译Nginx一: Nginx三个重要的使用场景 静态资源服务 疑问:为什么需要静态资源服务?答: 在整个的web请求…

string_string数据类型概括

目录string数据类型创建字符串的三种方式检查字符串的方法常用的字符串方法字符串遍历切割字符串为数组​截取子串判断某个字符串是否出现在当前字符串中文本匹配-match、(es6)matchAll文本替换-replace、(es6)replaceAll(es6)获取某个位置的字符串有关ASCII码的方法获取某字符…

Good Bye 2022: 2023 is NEAR C Koxia and Number Theory

Problem - C - Codeforces 题意: 给定一个数列a,问你是否存在一个数 x 使得所有数加上x之后两两互质 思路: 一、 我们知道一个结论,一些数两两之间互质,就说明所有数之间的质因子都不重合 如果要我们去判断一堆数…

回顾与展望Zebec举办的“Web3.0 TechHive Summit 2022 大会”

随着流支付生态 Zebec 不断的实现商业进展,我们看到,其生态从Solana陆续的迁移到以BNB Chain为代表的EVM链上,并推出了以ZK-Rollup为主要技术手段的公链Zebec Chain,以在未来服务且满足于Web2、Web3世界的发展需求。 Zebec正在成…

若依框架:前端项目结构与初始页面渲染流程

目录 main.js入口文件 前端页面初始化 package.json配置文件 vue-cli:.env模式和环境变量配置 vue-cli三大核心构件 CLI 服务与npm scripts vue-cli-service命令与.env模式配置文件 .env模式和环境变量配置 vue.config.js:项目启动-自动打开默认…

pycharm如何设置python文件模板

pycharm如何设置python文件模板设置文件模板预定义变量设置自定义模板变量设置文件模板 打开设置界面 进入编辑器->文件和代码模板 此处我只写了文件头注释模板,也可以加一些默认代码,比如: python if __name__ "__main__":…

NC65在单据添加按钮跳转到固定单据,且进行数据初始化

实现功能 下面两个是按钮 下面红框里面的内容是上面单据带过来的 上面就是本地代码实现的功能 具体实现代码 提前约定 为了方便称呼,这里把第一张图称为上游单据,第二张图为下游单据 所有代码AggVo都要替换成你自己的 配置文件 上游单据拓展配置文…

2023年天津美术学院专升本专业课线上考试安排准备及设备操作说明

天津美术学院2023年高职升本招生专业考试考生须知及操作说明一、考试时间安排二、考前准备 (一)纸张及其他材料(二)考试设备及网络 1.考生须提前准备好至少两部智能手机,为确保网络考试顺利进行,建议考生使用最近3年上市的主流品牌手机(如iPh…

太强了!这么设计中间件完美解决了百万并发的问题!

V-xin:ruyuan0330 获得600页原创精品文章汇总PDF 目录 一、大部分人对Java并发仍停留在理论阶段二、中间件系统的内核机制:双缓冲机制三、百万并发的技术挑战四、内存数据写入的锁机制以及串行化问题五、片机制 分段加锁机制 六、缓冲区写满时的双缓冲…

c++ - 第19节 - c++11

1.C11简介 c11简介:在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯…

Pycharm打开Project(工程)时停留在preparing workspace时间过长,导致打开很慢的解决方法...

Pycharm打开Project(工程)时停留在preparing workspace时间过长,导致打开很慢的解决方法… 昊虹君用Pycharm进行Python的开发,一直用得好好的,也没作过什么异常操作,但是从上星期开始,打开Project(工程)时停留在preparing worksp…

【王道操作系统】2.1.1 进程的定义、特征、组成、组织

进程的定义、特征、组成、组织 文章目录进程的定义、特征、组成、组织1.进程的定义2.进程的特征3.进程的组成4.进程的组织1.进程的定义 程序的概念: 进程的概念: 进程和程序的区别和联系: 区别: 进程是动态的,程序是静…

Linux系统下crond任务调度指令的常见用法

Linux系统下crond任务调度指令的常见用法 任务调度 任务调度是指系统在某个时间执行的特定的命令或程序。任务调度分类:1)系统工作:有些重要的工作必须周而复始地执行。如病毒扫描等;2)个别用户工作:个别用户可能希望执行某些程序,比如对mysql数据库的备份。 基本语…