Gradle学习笔记之依赖

本文详细介绍了Gradle中的依赖管理,包括直接依赖、项目依赖和本地jar包依赖的使用方式。同时,阐述了api和implementation的区别,以及如何处理依赖冲突,包括移除依赖、禁止传递依赖和强制使用特定版本。此外,还提到了配置Gradle在遇到依赖冲突时立即构建失败的解决方法。
摘要由CSDN通过智能技术生成

依赖的方式

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()
    }
}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值