Gradle和Maven有很多类似的地方,比如采用坐标Maven中采用groupId,Gradle中采用group
来配置和管理依赖,但不得不说Gradle确实比Maven强大,总的来说Gradle采纳了Maven和Ant两者的优点,下面这篇官方教程将带你入门Gradle。
Gradle入门(翻译自Graddle官网)
这样子讲可能会通熟一点,我尽量结合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')
}
复制代码