插件
Gradle自身(内核)并没有提供太多真实世界中我们常用的自动化任务。所有那些有用的特性,比如:编译Java源代码,打包Jar文件等,都是由插件提供的。
插件,顾名思义,是来自于外部,插入到Gradle中具有特殊功能的组件。插件为构建提供的新的功能(任务)和对应的配置(包含默认配置=约定),比如Java插件中的SourceSet决定了Java源代码的位置是src/main/java。
插件可以做很多事情:
- 扩展Gradle的模型(例如:添加新的可配置的DSL)
- 实现基于约定的构建(添加新的任务和有意义的默认配置)
- 应用指定的配置(比如:添加组织机构内部远程仓库,以及一些强制标准)
而这样做,所带来的好处是:
- 提高重用性,减少跨多个项目维护复杂逻辑的问题
- 更高级别的抽象,增强脚本的可理解性和组织性
- 封装必要逻辑,尽可能的让构建脚本具有声明性
插件类型
插件分为两种类型,脚本插件和二进制插件(编译成字节码后的插件)。
脚本插件,其实就是存在另一个脚本文件(other.gradle)的一段脚本代码,通常情况下存放在同一个构建项目下,主要作用是抽取逻辑,让关注点分离(separate of concern)。
二进制插件,则是编译后的class文件,它们通过实现Gradle API中的Plugin接口,通过编程的方式操作构建过程。二进制插件可以在直接在构建脚本(build.gradle)中写,也可以是一个单独的project中(独立的项目模块),又或者来自于一个Jar文件(最常用的做法)。
插件的使用
apply from: 'other.gradle' // 使用脚本插件
apply plugin: 'java' // 使用二进制插件
使用插件的方式是调用Project对象的Project.apply(java.util.Map)方法。在二进制插件的使用中,传入的参数(比如‘java’),叫做plugin id。这个id必须是唯一的,一些核心的插件,Gradle给他们提供了简短的名字,比如:java。而社区的插件,名字则会采用完整名字,比如:me.zeph.database。
如何使用社区插件?
插件就是编译过的实现了Plugin接口的class文件,封装在Jar文件中。Gradle对于核心的插件,已经将其作为Gradle发布版本的一部分,所以只需要直接调用apply就可以了。
然而,对于非核心的插件(社区插件),你必须将对应的Jar文件,放置到Gradle的classpath下,才能使用,这个道理很简单,它就和你使用第三方依赖(Spring,Hibernate)的道理一样。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1"
}
}
apply plugin: "com.jfrog.bintray"
下面是我实现的一个二进制插件,用来重置数据库,源代码和使用方式如下:
https://github.com/benweizhu/gradle-database-plugin
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'me.zeph:gradle-database-plugin:0.0.3'
}
}
apply plugin: 'me.zeph.database'
configurations {
database
}
dependencies {
database 'mysql:mysql-connector-java:5.1.18'
}
database {
url = 'jdbc:mysql://localhost:3306/'
username = 'root'
password = ''
databaseName = 'your_database'
driver = 'com.mysql.jdbc.Driver'
configurationName = 'database'
sqlFiles = files('config/database/my_sql.sql')
queryParameters = '?useUnicode=true&characterEncoding=UTF-8'
}
目前,Gradle提供了一种新的定义插件的方式,不在需要使用buildscript,不过了解它的本质还是很重要的。
通过plugin的DSL使用插件(新的方式,仍在开发阶段)
新的DSL提供了一种更加简明,方便的方式来定义插件。
plugins {
id 'java'
}
新的方式应用社区插件,不在需要使用buildscript,Gradle会根据插件的id,自动解析,定位。
plugins {
id "com.jfrog.bintray" version "0.4.1"
}
新的定义方式会做这样几件事情:
- 优化插件class的加载和重用
- 允许不同的插件使用不同版本的依赖(插件也是Jar文件,也有它自己的依赖)
新的定义方式的限制:
- plugins{}代码块只能在构建脚本中使用
- 不能和subprojects {}, allprojects {}结合使用(未来可能会解除这个限制)