Gradle和Maven有很多类似的地方,比如采用坐标Maven中采用groupId,Gradle中采用group
来配置和管理依赖,但不得不说Gradle确实比Maven强大,总的来说Gradle采纳了Maven和Ant两者的优点,下面这篇官方教程将带你入门Gradle。
这样子讲可能会通熟一点,我尽量结合Gradle和Maven之间的差异来进行讲解,因为很多人基本上都是从Maven转到Gradle,或者说之前有了解过Maven,小编是之前一直使用Maven,现在使用Gradle。
一、Gradle中的Project
1、Project
是什么?
首先我们应该明白一点,Maven和Gradle都是项目管理工具,那么很明显项目
是它们的基本组件,或者也可以将项目
说成工程
,本质上也是一样的。在Gradle中,一个工程就是一个Project
,这样讲可能会很抽象,如果我告诉你Project
是Gradle源代码的一个接口以及我们可以通过编程的方式来和Gradle的所有特性,(如依赖管理)打交道,你可能就会明白了。
2、我们怎么使用Project
?
有一个很明显的问题就是我们必须要编程才能和Gradle打交道吗?答案是否定的,如果你已经阅读了上面那篇入门教程,你应该知道Gradle工程下会有一个叫build.gradle
的文件,没错,这个文件就是Gradle工程的配置文件,而且是一对一的,一个Gradle工程有且只有一个build.gradle
配置文件。
这和Maven一样,每个工程对应一个pom.xml
文件
3、Gradle是如何根据build.gradle
配置文件管理我们的工程的,即生命周期是什么?
在构建初始化阶段,Gradle根据build.gradle
组装工程的大致流程如下:
- 1、创建一个
Settings
实例,如果Gradle工程下的settings.gradle
文件存在,则该文件将被解析成一个Settings
实例 - 2、根据
settings.gradle
文件对工程进行配置 - 3、使用
Settings
实例创建Project
实例的结构 - 4、最后,通过对项目执行build.gradle文件(如果存在)来评估每个项目
4、build.gradle
文件如何配置
你可能很想知道我该如何对一个build.gradle
进行配置,首先你已经知道一个工程对应一个build.gradle
文件,也就是说一个build.gradle
文件就对应一个Project
实例,那么Project
实例具有的属性你都可以使用。
在build.gradle
文件中采用DSL
进行配置,下面是你可以在build.gradle
文件中配置的内容:
-
Task
Task
是一种任务,任务是Gradle中的基本组件,Task
的概念也是收到了Ant
的启发而设计的 -
Dependencies
依赖管理
-
Plugins
插件,就像我们在Maven的
pom.xml
文件中增加插件一样,Gradle也可以添加插件,常见的插件有java
,eclipse
,我们可以使用apply plugin: 'java'
加载插件 -
Properties
属性配置
-
Methods
配置一个方法,纳尼,配置文件可以配置一个方法,你特么在逗我!没错,这就是
DSL
的魅力,DSL
内置支Groovy
这种脚本语言,因此,我们可以在build.gradle
文件中编写相关符合groovy
语法的代码,因此,换句话说,build.gradle
文件已经超出了配置文件的范畴,看起来更像是一个脚本文件,比配置文件更加强大。 -
Script Blocks
脚本块是个很强大的特性,也是Gradle特有的。上面说到其实
build.gradle
文件相当于一个脚本文件,因此脚本块的出现也就不足为奇了。常用的脚本块有以下几种:-
allprojects
在多项目工程中对所有项目(包括子项目)的通用配置
-
ant
对ant提供支持
-
artifacts
对生成构件的支持,如生产一个jar包
-
buildscript
执行
gradle build
命令的相关配置,主要配置构建的输出目录,引用的仓库等信息 -
configurations
提供对依赖管理的支持
-
dependencies
依赖的声明和配置
-
repositories
仓库配置
-
subprojects
在多项目中对所有子项目的通用配置
-
二、Gradle中的Properties
1、Gradle中的属性
Gradle根据Project
实例执行项目的构建文件以配置项目。你的脚本使用的任何属性或方法都被委托给关联的Project
对象。什么意思呢?也就是说你可以直接在脚本中使用Project
接口上的任何方法和属性。
举个例子:
defaultTasks('some-task') // Delegates to Project.defaultTasks()reportsDir = file('reports') // Delegates to Project.file() and the Java Plugin复制代码
上面在脚本中配置了一个方法和一个属性,这两个配置都将会被应用到Project
实例上去。
当然,你也可以使用project
属性来表示Project
,即使用project
直接对Project
实例的相关属性方法进行调用,这可以在某些情况下使脚本更清晰。例如,你可以使用project.name
而不是name
来访问项目名称。
一个project
将从5个作用域来查找相关属性,你可以在构建文件中按名称访问或通过调用项目的Project.property(java.lang.String)
方法这些属性,5个作用域分别如下:
-
1、
Project
本身。此作用域包括由
Project
实现类声明的任何属性setter
和getter
方法。例如,我们可以通Project.getRootProject()
可以作为rootProject
属性值。根据相应的getter
或setter
方法的存在,此作用域的属性是可读或可写的。 -
2、
project
的extra
属性每个项目都维护一个
extra
属性的映射,其中可以包含任意名称->值对。一旦定义,这个作用域的属性也是可读写的。 -
3、插件添加到项目的扩展属性
每个扩展名都可用作只读属性,其名称与扩展名相同。
-
4、由插件添加到项目中的约定属性
插件可以通过项目的
Convention
对象将属性和方法添加到项目中。该范围的属性可能是可读或可写的,具体取决于约定对象。 -
5、
task
当成一个属性通过使用其名称作为属性名称可以访问任务。这个范围的属性是只读的。 例如,一个名为
compile
的任务可以作为compile
属性访问。
extra
属性和约定属性从项目的父项继承,递归到根项目。 此作用域的属性是只读的。
读取属性时,项目按顺序搜索上述范围,并从找到该属性的第一个范围返回值。如果没有找到属性,Gradle就会报错。
在设置属性时,项目按顺序搜索上述范围,并将属性设置在第一个找到该属性的范围中。
2、Extra
属性
所有Extra
属性必须通过ext
命名空间来定义。 一旦定义了一个Extra
属性,它就直接在拥有的对象上(在下面的例子中分别是项目,任务和子项目)可用,并且可以被读取和更新。 Extra
属性只有通过命名空间ext
进行声明和初始化后才能使用。
比如下面列出了3个不同作用域下的Extra
属性:
// Project本身project.ext.prop1 = "foo"// 任务task doStuff { ext.prop2 = "bar"}// 子项目下subprojects { ext.${prop3} = false }复制代码
读取Extra
属性是通过ext
或通过拥有的对象完成的。
ext.isSnapshot = version.endsWith("-SNAPSHOT")if (isSnapshot) { // do snapshot stuff}复制代码
更多属性可以查阅
三、Gradle配置简单的多项目工程
该工程为Spring boot
工程,大家可以通过http://start.spring.io/
配置下载,主工程包含三个子工程,分别是myapp-controller
,myapp-service
,myapp-dao
项目结构图如下:
根目录下的settings.gradle
rootProject.name = 'myapp'include 'myapp-controller'include 'myapp-service'include 'myapp-dao'复制代码
build.gradle
// 构建脚本buildscript { ext { springBootVersion = '2.0.2.RELEASE' } repositories { mavenCentral() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }}// 所有项目共有的配置allprojects { apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } dependencies { compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') }}复制代码
每个子工程下的buide.gradle
description = 'myapp-controller'dependencies { // 该子工程包含另外一个子工程 compile project(':myapp-dao')}复制代码