Gradle最佳实践
一、Gradle相比Maven的优势
配置简洁
Maven是用pom.xml管理,引入一个jar包至少5行代码,Gradle只需要一行。
构建速度快
Gradle支持daemon方式运行,启动速度快,同时有基于daemon的增量构建,充分利用JVM的运行时优化,和缓存数据构建速度相比Maven快很多。
更好的灵活性、扩展性
Gradle 相对于 Maven 等构建工具, 其提供了一系列的 API 让我们有能力去修改或定制项目的构建过程。
二、基本配置
设置本地仓库地址
默认本地仓库地址是:~/.gradle,Windows下会占用大量C盘空间。
设置环境变量,GRADLE_USER_HOME=/your/path
复用Maven本地仓库
在repositories配置mavenLocal()即可,如果是init.gradle全局配置,参考以下init.gradle文件
Maven本地仓库查找路径:
(1)USER_HOME/.m2/settings.xml
(2)M2_HOME/conf/settings.xml
(3)USER_HOME/.m2/repository
国内镜像加速
国内访问国外仓库地址很慢,第一种方法是在每个项目中设置repositories
repositories {
mavenLocal()
'maven(http://maven.aliyun.com/nexus/content/groups/public/)'
mavenCentral()
}
更推荐的方式是类似的Maven的settings.xml全局的配置,在上一步配置的GRADLE_USER_HOME路径下,添加init.gradle文件,以下配置文件中使用了阿里云的Gradle代理,支持jcenter、google、maven仓库。
gradle.projectsLoaded {
rootProject.allprojects {
buildscript {
repositories {
def JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter'
def GOOGLE_URL = 'https://maven.aliyun.com/repository/google'
def NEXUS_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
all { ArtifactRepository repo ->
if (repo instanceof MavenArtifactRepository) {
def url = repo.url.toString()
if (url.startsWith('https://jcenter.bintray.com/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $JCENTER_URL."
println("buildscript ${repo.url} replaced by $JCENTER_URL.")
remove repo
}
else if (url.startsWith('https://dl.google.com/dl/android/maven2/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $GOOGLE_URL."
println("buildscript ${repo.url} replaced by $GOOGLE_URL.")
remove repo
}
else if (url.startsWith('https://repo1.maven.org/maven2')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
println("buildscript ${repo.url} replaced by $REPOSITORY_URL.")
remove repo
}
}
}
jcenter {
url JCENTER_URL
}
google {
url GOOGLE_URL
}
maven {
url NEXUS_URL
}
}
}
repositories {
def JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter'
def GOOGLE_URL = 'https://maven.aliyun.com/repository/google'
def NEXUS_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
all { ArtifactRepository repo ->
if (repo instanceof MavenArtifactRepository) {
def url = repo.url.toString()
if (url.startsWith('https://jcenter.bintray.com/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $JCENTER_URL."
println("buildscript ${repo.url} replaced by $JCENTER_URL.")
remove repo
}
else if (url.startsWith('https://dl.google.com/dl/android/maven2/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $GOOGLE_URL."
println("buildscript ${repo.url} replaced by $GOOGLE_URL.")
remove repo
}
else if (url.startsWith('https://repo1.maven.org/maven2')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
println("buildscript ${repo.url} replaced by $REPOSITORY_URL.")
remove repo
}
}
}
jcenter {
url JCENTER_URL
}
google {
url GOOGLE_URL
}
maven {
url NEXUS_URL
}
}
}
}
三、最佳实践
多模块配置
稍微大点的项目都会分模块开发,Gradle相比Maven的一个优势是用IDEA执行一个项目的代码时,会自动编译其依赖的其他模块。
在项目一级目录下添加settings.gradle配置文件:
rootProject.name = 'my-roject-name' include 'module1'
include 'module2'
其中module1、module2就是子模块的文件夹名,在子模块里需要有一个配置子模块的build.gradle
模块内依赖,比如module2依赖module1,在module2的build.gradle配置文件里添加:
dependencies {
compile project(":module1")
}
profile支持
profile用来加载不同环境的的配置文件,在笔者所在公司,推荐dev、test、staging、prod四套环境。
添加gradle.properties配置文件指定默认profile
profile=dev
启动profile,加载不同路径下的配置,在build.gradle里添加配置:
ext {
profile = project['profile']
}
sourceSets {
main {
resources {
srcDirs = ["src/main/resources/", "src/main/profiles/${profile}"]
}
}
}
命令行参数指定profile:
gradle build -Pprofile=prod
初始化gradle项目
安装gradle,并在项目顶级目录下执行:
gradle init
如果当前目录有pom.xml,接下来会提示是否从Maven项目初始化Gradle项目,选择yes回车执行。
参数文档:https://docs.gradle.org/current/userguide/build_init_plugin.html
引入bom文件
pom文件在Maven中是一个很有用的功能,方便多个项目统一版本号,在Maven中配置方式如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Gradle有插件支持类似操作:
//引入插件
plugins {
id "io.spring.dependency-management" version "1.0.10.RELEASE"
}
//引入bom
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-dependencies:${spring-boot.version}'
}
}
//使用bom,不需要执行版本号
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web"
}
引入parent文件
在maven中执行parent是管理多个项目常用的方式,parent指定了项目的基本配置,配置方式如下:
<parent>
<groupId>com.lesofn.blog</groupId>
<artifactId>test-parent</artifactId>
<version>0.0.1</version>
</parent>
Maven中的parent有两个作用,一个是类似bom的统一管理版本,即parent中的:dependencyManagement,另一个是基础jar包的引用,即父pom中的:dependencies
在Gradle可通过上面的io.spring.dependency-management插件实现类似的效果:
//引入插件
plugins {
id "io.spring.dependency-management" version "1.0.10.RELEASE"
}
//引入parent,实现maven中dependencyManagement的功能,不用指定版本号
dependencyManagement {
imports {
mavenBom 'com.lesofn.blog:test-parent:0.0.1'
}
}
//再次引入parent,实现maven中dependencies的功能
dependencies {
implementation 'com.lesofn.blog:test-parent:0.0.1'
}
四、总结
经过以上配置,基本覆盖了Gradle开发过程中的大部分问题,如果还有什么问题,欢迎留言讨论。
本文作者:木小丰,美团Java高级工程师,关注架构、软件工程、全栈等,不定期分享软件研发过程中的实践、思考。
博客地址:https://lesofn.com/archives/gradle-zui-jia-shi-jian
公共号:Java研发

Gradle最佳实践的更多相关文章
- build.gradle最佳实践之buildConfigField
使用AndroidStudio进行开发,其中很重要的一个文件就是build.gradle,他是整个项目的控制中心,这里收集一些日常会用到的语法或者使用技巧,以备后用.这篇博客主要说明 buildTyp ...
- Gradle配置最佳实践
https://blog.csdn.net/devilnov/article/details/53321164 本文会不定期更新,推荐watch下项目.如果喜欢请star,如果觉得有纰漏请提交issu ...
- Spring Batch在大型企业中的最佳实践
在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...
- Google Developing for Android 二 - Memory 最佳实践 // lightSky‘Blog
Google Developing for Android 二 - Memory 最佳实践 | 分类于 Android最佳实践 原文:Developing for Android, II Th ...
- [转]Android开发最佳实践
——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢—— 原文链接:https://github.com/futurice/and ...
- mybatis 3.x源码深度解析与最佳实践(最完整原创)
mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...
- 听说你还不会用Dagger2?Dagger2 For Android最佳实践教程
前言 Dagger2是现在非常火的一个依赖注入框架,目前由Google维护,在Github上面已经有12K star了.Dagger2的入门门槛其实是比较高的,据了解,目前有很多Android工程师对 ...
- Android学习之基础知识七—碎片的最佳实践
一.Android碎片(Fragment)的最佳实践——简易版新闻应用 第一步:新建FragmentBestPractice项目,在app/build.gradle当中添加:RecyclerView ...
- Android开发最佳实践
Android开发最佳实践 摘要 ●使用 Gradle 和它推荐的工程结构 ●把密码和敏感数据放在gradle.properties ●不要自己写 HTTP 客户端,使用Volley或OkHttp库 ...
随机推荐
- 第 4篇 Scrum 冲刺博客
一.站立式会议 1.站立式会议照片 2.昨天已完成的工作 登录信息的匹配 3.今天计划完成的工作 ①售货员页面功能 ②销售排行 4.工作中遇到的困难 ①页面按钮太过复杂,逻辑错乱 ②有的同学数据库驱动 ...
- 【eJOI2020】考试(dp & 树状数组优化)
Description \(n\) 个正整数排成一列,每个位置 \(i\) 有一个初始值 \(A_i\) 以及目标值 \(B_i\). 一次操作可以选定一个区间 \([l, r]\),并将区间内所有数 ...
- 算法—— n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个 ...
- kylin的实现原理
摘自https://blog.bcmeng.com/post/kylin-cube.html#kylin%E7%9A%84%E9%A2%84%E8%AE%A1%E7%AE%97%E6%98%AF%E5 ...
- 封装事件订阅来进行非父子组件的传值(React)
const list={} // 将事件名和事件函数装进事件池里 function $on(name,func) { if(!name || !func) return; if(!Object.key ...
- 移动 WEB 开发的布局方式 ---- 响应式布局
一.响应式简介 一个页面布局兼容了 PC端 ,iPad端 和 移动端 所谓的响应式就是页面中的布局会随着屏幕的大小变化发生了响应而做出不同的页面布局模型 特点: 响应式布局是不需要单独写移动端页面的 ...
- 用列表+for循环生成乘法口诀表
1 # 结合一下列表生成, 准备设计乘法表 2 # numlist = [1,2,3,4,5] 3 # [pow(i,3) for i in numlist] 4 # ## [1, 8, 27, 64 ...
- typora软件使用指南
Markdown学习 标题: 三级标题 四级标题 字体 hello,world! hello,world! hello,world! hello,world! 引用 选择狂神说java,走向人生巅峰 ...
- UML—20—002
博客班级 < https://edu.cnblogs.com/campus/fzzcxy/2018SE1> 作业要求 <https://edu.cnblogs.com/campus/ ...
- 大数据组件Kerberos安全访问关键代码
版本信息 <version.hbase>2.1.0-cdh6.2.1</version.hbase> <version.hadoop>3.0.0-cdh6.2.1& ...