Gradle对Maven的改进
聊了Maven的思路和优势,那Maven的缺点呢?这个我们和Gradle一起聊聊。Gradle就是在Maven的基础上进行的改进。优势主要体现在以下方面:
1.配置语言
Maven使用的是XML,受限于XML的表达能力以及XML本身的冗余,会使pom.xml文件显得冗长而笨重。而Gradle是基于Groovy定义的一种DSL语言,简洁并且表达能力强大。在Maven中,任何扩展都需要通过Maven插件实现,但Gradle的配置文件本身就是一种语言,可以直接依赖任意Java库,可以直接在build.gradle文件中像Ant一样定义task,比Ant的表达能力更强(Ant本身也是XML定义的)。
Gradle的配置文件中可以直接获取到Project对象以及环境变量,可以通过程序对build过程进行更细致的自定义控制,这个功能对于复杂的项目来说非常有用。
2.项目自包含(Self Provisioning Build Environment)
用户下载了一个Maven定义的项目,如果没用过Maven,还需要下载Maven工具包,了解Maven。但Gradle可以给项目生成一个 gradlew脚本,用户直接运行gradlew脚本即可,该脚本会自动检测本地是否已经有Gradle,没有则从网络下载,对用户透明(当然,国内网络下最好还是自己先下载好)。
对仓库的配置,Maven提供了一个本地的settings.xml配置文件,用于定义私有仓库以及仓库密码这样敏感的不应该放源码仓库里的文件。但这样带来的不便就是这些信息项目中没有自包含,所以Gradle干掉了这种本地配置的机制,所有的定义都在项目里。私有仓库密码这样的可以放在项目下的 gradle.properties文件里不提交上去,通过其他方式分享给内部成员。这点可能各有优劣。
3.任务依赖以及执行机制
Maven的构建生命周期的每一步都是预定义好的(参看前文),插件任务只能在预留的生命周期中的某个阶段切入,虽然Maven的生命周期阶段考虑很充分,但有时候也不能满足需求。Maven会严格按照生命周期的阶段从开始线性执行任务,而Gradle则使用了Directed Acyclic Graph来检测任务的依赖关系,决定哪些任务可以并行执行,这样使任务的定义以及执行都更灵活。
4.依赖管理更为灵活
Maven对依赖管理比较严格,依赖必须是源码仓库的坐标。虽然也支持system scope的本地路径配置,但还是有许多不方便之处(system scope的依赖,打包的时候不包含进来)。如果世界上所有的库都通过Maven发布,当然没有问题,但现实往往不是这样的。这里要吐槽一下国内的各大厂发布的sdk之类的库,几乎都不提供仓库地址,就给个压缩包放一堆jar包进来,让用户自己搞定依赖管理问题。而Gradle在这方面比较灵活,比如支持:
- compile fileTree(dir: 'libs', include: '*.jar')
这样的配置规则。
另外由于Gradle本身是一种语言,可以用编程的方式来管理依赖。比如大多数子项目都依赖某个库,除了个别几个,就可以这样写:
- configure(subprojects.findAll {it.name != 'xxx1’ && it.name != ‘xxx2’}) {
- dependencies {
- compile("com.google.guava:guava:18.0”)
- }
- }
5.子项目以及动态依赖机制
动态依赖主要是用来解决几个互相依赖的库都在快速开发期间的依赖问题,不能每次地层库修改发布新版本,上层库都要修改依赖配置文件,所以需要动态设置依赖最新版本。
Maven的解决方案是SNAPSHOT机制,子项目之间也是通过这个机制来实现依赖的。遇到的问题我们前面也分析了。
Gradle的虽然也兼容Maven仓库的SNAPSHOT机制,但它自己的版本管理机制上,并没有引入SNAPSHOT机制。它的依赖支持4.x,2.+这样的配置规则,实现动态依赖(注:Maven也支持类似的规则,参看 Dependency Version Requirement Specification)。而子项目之间的依赖采用特殊的依赖配置,和第三方库的配置规则有区别。它直接使用:
- compile project(“:subpoject-name”);
这样的配置,无需配置版本号,明确指定是子项目,避免Maven的子项目依赖带来的版本号问题。子项目的配置中也不需要显示配置父项目,只需要父项目单向中配置子项目列表即可。
同时Gradle的release机制也更为灵活,支持release到各种仓库(包括Maven仓库),但不控制release过程中的版本号生成,修改源码仓库等步骤,留给用户自己通过手动或者CI工具,或者脚本去解决。
关于Gradle相对Maven的改进这里主要列举这几点,其他的可以参看Gradle官方的比较表格:maven_vs_gradle,这里不再详述。
Go语言的多项目以及依赖管理问题
最后再谈谈Go语言的多项目以及依赖管理问题。Go官方对这两方面并未做约定或者提供工具,于是只能各自想办法解决。多项目问题一般就是回归到了 Makefile+脚本的解决方案,比如kubernetes。依赖管理,开源社区多用Godeps,kubernetes用的也是这个。Godeps通过源码仓库路径以及源码tag来确定库的坐标,只管理依赖,有点像ivy,不关心构建过程。Godepes会将依赖库的依赖也添加到当前项目的依赖配置中,不是动态的依赖传递机制。没有scope,不区分是否是单元测试的依赖。一个仓库只支持一个配置,没有子项目概念,项目大了管理就比较复杂。另外它对传递依赖以及版本冲突的问题当前还是没有解决太好(有一些相关Issue)。
一个语言的多项目以及依赖管理方案对这个语言的生态发展有很大的影响,Java发展到现在,Maven以及Gradle功不可没,所以感觉Go官方应该对这两方面有所作为。Go语言迟迟没出依赖管理工具,个人觉得有几方面考虑:
1.Go尚未确定动态库的机制。编译型语言依赖最好也是二进制的,而不是源码。一方面可以加快编译速度,另外一方面也可以实现源码保护,方便分发以及代理缓存,让语言的适用范围更广。许多商业上的库是不方便提供源码的。所以依赖管理工具的实现需要动态库的机制。而动态库尚未确定的原因我觉得是Go 语言不想过早的引入二进制动态库的格式兼容问题,初期全部用源码是最省事的。
2.先让社区试试水,看看效果和反馈。
任何一个语言,发展到一定阶段都避不开依赖管理问题。前一段时间看到一篇写Go语言的文章,嘲讽Java的Maven构建个项目恨不能把半个互联网下载下来,我当时脑海中就浮现出长者的那句经典语录“图样图森破”。Go当前没遇到这些问题的原因只是Go还比较年轻,库还不够丰富,以及Go的很多项目还不够复杂。而像kubernetes这样的项目,当前依赖已经有226个了,构建一下,也快要下载半个Github了。所以个人觉得Go社区当前还是非常需要一个类似于Gradle的工具,来解决依赖管理,构建,多项目管理等问题。
相关推荐
Java社区有许多流行的工具,如Jenkins、Maven和Gradle,它们可以帮助自动化构建、测试和部署过程,提高软件开发的效率和质量。 总的来说,"基于计算机软件开发的JAVA编程应用初探"这份资料将带领我们从基础到高级,...
1. 引入JUnit4依赖:在项目构建文件中(如Maven或Gradle)添加JUnit4的依赖。 2. 创建测试类:创建一个类,并使用`@RunWith(JUnit4.class)`注解标记为JUnit4测试类。 3. 编写测试方法:使用`@Test`注解标记测试方法...
对于Java项目,可以通过Maven或Gradle添加相应的依赖项。 2. **创建索引**:创建一个`Directory`对象,这可以是内存目录或磁盘上的文件系统目录。然后,实例化一个`IndexWriterConfig`并配置分析器。接着,使用`...
### Kotlin初探与集成Android项目 #### 一、了解Kotlin **Kotlin的背景:** Kotlin 是一种由 JetBrains 开发的静态类型编程语言,它最初发布于 2011 年,并且在 2017 年被 Google 宣布成为 Android 的官方开发...
1. 添加相关依赖:在项目中引入Spring和MyBatis的库,通常通过Maven或Gradle的依赖管理来完成。 2. 配置MyBatis:创建mybatis-config.xml文件,定义数据源、事务管理器以及SqlSessionFactory。 3. 配置Spring:在...
在"OpenCV初探:二、Android程序示例 源代码"中,我们可以预期获得一些关于如何在Android应用中集成OpenCV的实例代码。这些源代码将帮助开发者理解如何在Android环境下设置和使用OpenCV库,从而实现各种视觉任务。 ...
**Spring Boot 初探:构建你的第一个应用** Spring Boot 是由 Pivotal 团队提供的全新框架,旨在简化 Spring 应用程序的初始搭建以及开发过程。它集成了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、...
【项目HandGradle:Java Gradle项目初探】 在IT行业中,项目管理工具对于软件开发至关重要,它们自动化了构建、依赖管理和打包等繁琐任务。在Java世界里,Gradle是广泛应用的一款高级构建工具,它以其灵活性和强大...
此外,Maven或Gradle这样的构建工具可以帮助管理项目依赖和构建过程。 总的来说,JSP和Servlet是Java Web开发中的重要组成部分,通过HTTP服务器,它们能提供动态交互的Web服务。理解和掌握这两者对于Java Web开发者...
然而,在本文的初探阶段,我们不会深入讨论这些高级特性。 为了开始使用RecyclerView,你需要在项目中添加相应的依赖库。例如,可以添加以下依赖到build.gradle文件中: ```gradle compile '...
Android Studio 3.6 中的 View Binding 初探及用法区别 View Binding 是 Android 中的一项功能,旨在帮助开发者更轻松地编写与视图交互的代码。在模块中启用视图绑定后,它将为该模块中存在的每个 XML 布局文件生成...
《构建基于Kotlin的Mirai Console Plugin:simple-mirai-thesaurus初探》 在IT领域,开发高效、易用的插件是提升工作效率的关键。"simple-mirai-thesaurus"是一个专为Mirai Console设计的插件模板,采用现代编程...
《穆易天气APP:Android Studio开发初探》 在当今移动互联网时代,手机应用程序(App)已经成为人们日常生活不可或缺的一部分。本文将围绕“穆易天气”这个应用,详细探讨其背后的技术实现,以及如何使用Android ...
- `build.gradle`:项目构建配置文件,定义了依赖项和构建规则。 - `model.tflite`:预训练的 TensorFlow Lite 模型文件。 - `AndroidManifest.xml`:应用的配置文件,声明权限和活动。 - `activity_main.xml`:应用...
#### 二、Spring初探与准备工作 - **环境搭建**:Spring开发前,需要搭建合适的开发环境,包括但不限于配置Java开发工具(如Eclipse或IntelliJ IDEA)、安装JDK、设置Maven或Gradle构建工具等。 - **构建Spring基础...
【Android应用开发】初探:从“您好,中国!”到构建你的首个项目 在Android应用开发的世界里,迈出第一步至关重要。"第一个Android应用-您好,中国!" 是一个引导性的项目,旨在帮助初学者理解基本的Android ...