简单的介绍一下Gradle
Introduction
- Gradle是一个通用的项目构建工具(官方说像Ant一样,反正我没用过…所以我不懂),它不单单可以用来构建Java项目,还可以用来构建各种语言相关甚至非语言相关的项目,一切都决定于你想用它来干什么
- Gradle是一个遵循约定大于配置的项目构建工具(像Maven一样,这回我用过,所以就不加官方说了),但是它的一起操作都支持自定义.但是为了世界和平,我个人觉得还是尽可能遵循约定会比较好
- Gradle支持多项目构建,而且功能非常的强大,真的非常强大,已经不是Maven可以比拟的了,Gradle甚至可以把非同一项目根目录的项目引用到你的项目里面来进行项目构建,虽然这个功能现在只是处于孵化阶段(这个东西叫 Composite Builds 翻译成中文应该是叫混合构建吧).
- Gradle拥有非常强大的依赖管理,反正Maven repository,Ivy repository, Local repository,甚至是你随便丢的依赖(包括网络上的),它都可以帮你正确的引入进来.在多项目构建的时候,它还可以直接引入你的项目作为依赖,如果你愿意的话,它还可以把用这个引入的项目来替代你引入的正式发布的依赖
- Gradle为你解决了循环依赖噩梦,有很多配置可以让你选择,它默认会为你把依赖提高到你所有引用到的最高版本.(就是说,例如你某个依赖用的1.0版本,另一个用了2.0版本,最后依赖统一都提高到2.0版本)
- Ant被完全融合进了Gradle
- Gradle也支持插件的功能,而且它的插件不像Maven一样,Gradle本身只是相当于一个框架的存在,所有真正的构建动作都是由指定的插件去完成.而Maven的插件只是在对Maven的功能上的扩展.
- Gradle 的构建靠的就是一个非常强大的脚本,脚本语言是基于Groovy的DSL(Domain Specific Language),所以它也支持所有的Groovy语法.它不像Maven靠的是xml静态配置文件,既然Gradle的构建脚本是可编程的,它的灵活性就不用我多说了,最简单的例子就是,Gradle的插件可以让用户做到,在指定的动作上面直接添加用户自定义的动作,这不是简单的xml可以做得到的
The Build Lifecycle
官方文档把这个放在很后面去介绍,我觉这个应该放在这里说,要不然看的人云里雾里(起码要简单的结束一下嘛).总的来说Gradle的脚本执行就分2个阶段,配置阶段,和执行阶段,默认情况下,这些阶段都由build.gradle和settings.gradle这2个脚本文件来完成了( settings.gradle 只在多项目构建的时候才有用).下面简单的说一下:
- Configuration
- 首先是配置阶段,在这个阶段下所有脚本里面的代码都会被Gradle加载,而且执行对应的配置,赋值,初始化等工作
- Execution
- 然后这里是重头戏了,Gradle一切的执行都是靠Task,在完成了所有的初始化工作之后,Gradle就会执行用户命令行输入的目标Task去完成脚本上的一切执行动作(注意Task是分执行部分和配置部分的,这里只是简介一下Gradle我就不赘述了,有兴趣的请自行查阅Gradle用户文档,不谢),然后你想做的一切,就会为你完成了.
- 在构建的时候,Gradle会生成很多对象,然后你可以在你的脚本里调用这些对象的属性.
Groovy Quickstart
反正用Gradle你就跑不掉要基本理解下Groovy,基本的语法你还是得知道,Gradle的官方文档有这个一个章节,Chapter 53. Groovy Quickstart,反正也可以看一下.值得注意的是,Gradle大量地使用了Groovy闭包的Delegation机制和Bean的概念(也可以看看这里的讲解),先理解这些,看Gradle的脚本就不会觉得懵逼
About Task
Task是Gradle灵魂一样的存在,所有真正的执行动作都是有Task去完成,例如:
task hello {
doLast {
println 'Hello world!'
}
}
然后执行 gradle -q hello 就会输出
> gradle -q hello
Hello world!
就会输出 ‘Hello world!’ 了 这意味着什么?这个是脚本语言,你可以自己写一个Task然后把你的代码填进去,然后命令行执行一下,你就可以做 做 What ever you want!!!!
然后这个Task还可以继承,(好像可以复写,但是这个比较复杂了)
task taskX(dependsOn: 'taskY') {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
然后执行 gradle -q taskX 就会输出
> gradle -q taskX
taskY
taskX
看这样就会先执行taskY再执行taskX,现在的例子看起来简单,但是当父Task的功能非常通用,强大的时候,想要继承实现这个父Task功能就会变的非常简单了.来再开个例子
task copyDocs(type: Copy) {
from 'src/main/doc'
into 'build/target/doc'
}
就这样,执行一下gradle -q taskX,src/main/doc 里面的文件就会被复制到 build/target/doc里面了,是不是非常简单!
About Plugin
然后牛逼的东西来了,因为Gradle有上面累述的特性,它的插件就变得异常的强大了,例如你本来构建的是Java,换个插件你就可以构建golang项目了,当然这里我说的夸张了,还是要改挺多东西的.举个栗子: 默认的java插件在打包的时候是不会把依赖都打进jar里面的,然后我加个插件(这个插件叫shadow)
plugins {
id 'java'
id "com.github.johnrengelman.shadow" version "1.2.4"
}
shadowJar {
manifest {
attributes 'Main-Class': 'app.SingleServerMain'
}
}
然后执行 gradle -q shadowJar -x Jar 依赖就全打进jar里面了.可能有同学说,这和Maven有什么区别.那就再举个简单的栗子
plugins {
id 'java'
id "com.github.johnrengelman.shadow" version "1.2.4"
}
shadowJar {
manifest {
attributes 'Main-Class': 'app.SingleServerMain'
}
}
//只加了这个
shadowJar.doLast {
println 'pack finished!!!!!'
}
上面我只加了一句,但是Maven就绝对做不到了,更牛逼的功能,我在这就不累述了. 啊,对了,Gradle还有它自己的插件库,找插件就再也不用妈妈担心了Gradle Plugins
Finally
上个对比图Gradle vs Maven
实现同样的项目构建功能,Gradle 194行,Maven 506行,Gradle完胜.虽然Gradle的学习曲线要比Maven平滑很多,但是那个官方文档还是看的人一个蛋疼,很多坑在里面.