体验Gradle(5):插件

Gradle明确提出了插件的概念,这是它与Ant的最大区别。虽然后者也支持自定义任务来扩展自己的功能,但它没有插件的概念。Gradle则不然,通过将功能围绕插件进行组织,不仅方便了常用功能的复用,而且也非常容易的可以实现新功能的扩展。在本系列的第一篇里,我们就用Groovy插件编写了一个Groovy工程的例子。

简单地讲,插件就是“任务+惯例”的集合,前者给出了我们可以在构建逻辑里直接使用的Task,后者则给出了缺省的配置值。使用现成的插件非常容易,在第一篇里已经给出了一种方式:

usePlugin 'groovy'

仅仅一句话,我们即可享受Groovy工程的缺省配置,以及工程要用到的任务。是不是非常类似Java里的“Import ……”?除了这种方式,我们还可以在usePlugin里使用类名,告诉Gradle插件类是什么:

usePlugin org.gradle.api.plugins.JavaPlugin

实际上,这才是正统的引入插件方式。而第一种,则是因为Gradle已经做了一些“暗箱操作”。如果你也想能够通过字符串来引入自定义插件,而不是输入一大串类名,那么就需要修改Gradle自带的plugin.properties文件(位于Gradle的根目录),形式为:字符串名=类名。这里有几行摘自该文件的例子,应该很能说明问题了:

java=org.gradle.api.plugins.JavaPlugin
groovy=org.gradle.api.plugins.GroovyPlugin

至于每个插件的任务和惯例,那就是随插件的不同而不同了。关于这些内容需要查看插件的文档,如果是Gradle自己的插件,那直接浏览参考文档就好了。

跟命令行中指定的任务类似,对于每个插件,Gradle只会为一个工程调用一次,不受插件声明次数的影响。这在某些插件之间存在继承关系时尤其重要,如Groovy插件便是Java插件的子类,那么:

//方式1
usePlugin 'groovy'

//方式2
usePlugin 'java'
usePlugin 'groovy'

方式1和方式2的效果完全一样,这无疑对于负责书写构建逻辑的我们来讲要方便和清晰很多。

实现自定义插件并不复杂,只需要实现Plugin接口就行了,其中的use方法是关键,它会被Gradle调用。

usePlugin(GreetingPlugin)
class GreetingPlugin implements Plugin {
    def void use(Project project, ProjectPluginsContainer projectPluginsHandler) {
        project.task('hello') << {
            println "Hello from the GreetingPlugin"
        }
    }
}

从代码上看,任务是在use中添加的,这样当Gradle调用use时,项目中自然就有了我们定义的任务。这便是为什么只要引入插件后,插件的Task就能为我们所用的原因。在参考文档里还给出了定义管理的例子,这里就不在列出了。插件的代码可以位于build.gradle里,也可以位于rootProjectDir/buildSrc/src/main/groovy中。

值得注意的是,插件并不是一定就要用Groovy编写,你可以在Gradle的src\org\gradle\api\plugins\目录下发现大量用Java写的插件,非常具有参考价值。


本系列的其它部分:

By foxgem - Posted on 18 七月 2010