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文件中配置的内容:

  • TaskTask是一种任务,任务是Gradle中的基本组件,Task的概念也是收到了Ant的启发而设计的
  • Dependencies依赖管理
  • Plugins插件,就像我们在Maven的pom.xml文件中增加插件一样,Gradle也可以添加插件,常见的插件有javaeclipse,我们可以使用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实现类声明的任何属性settergetter方法。例如,我们可以通Project.getRootProject()可以作为rootProject属性值。根据相应的gettersetter方法的存在,此作用域的属性是可读或可写的。
  • 2、projectextra属性
    每个项目都维护一个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')
}
复制代码