Gradle的增量构建
对Maven而言,在运行任务之前,检查以下所有编译输出的结构,如果是最新的class文件,就不需要再重新跑。它基于的标准是时间戳,假如当时间戳被改变,即使是最新的编译,也会重新运行。
在Gradle中,增量构建如下图所示:
官方操作手册
可以看到,左边的属性可以认为是输入,右边的是输出。当Gradle检查到输入和输出都没改变,就不进行构建。否则执行构建。
增量构建的核心是,只做那些改变的了事情,没有改变的事情不会去做。
task copyGradlew(type: Copy){
inputs.files(fileTree("gradlew"))
.withPropertyName("sourceFiles");
outputs.files(fileTree("gradlew"))
.withPropertyName("sourceFiles");
from "gradlew"
into 'target'
}
如上例子,这个task完成了把‘gradlew’复制到文件目录target
下,使用了Gradle自带的Copy
api,这里的inputs
和outputs
指的是运行时API,可以更灵活的规定输入和输出。
运行的结果:
第一次:
1 actionable task: 1 executed
第二次:
1 actionable task: 1 up-to-date
可以看到,当第二次运行的时候,依照上面图面说明,当输入输出并没有改变的情况下,gradle的增量构建不会再去执行这个task。
当然如果非得重新运行一遍,可以使用命令:
-- rerun-taks
Gradle的依赖管理
apply plugin: 'java'
repositories{
mavenCentral()
}
dependecies{
compile 'org.apache.commons:commons-csv:1.5'
runtimeOnly("com.inspur.cloud:liquibase-schema:3.6")
}
上面的代码是一段简单的Gradle的依赖管理。apply plugin: 'java'
的含义是声明了一个插件,这里的语法,实际上是apply ([plugin: 'java'])
,调用了apply
方法,传递了一个Map对象。
为什么要声明使用‘java’插件呢?因为在Maven中,像main目录,test目录等都是约定好了的。在Gradle中并不是,所以得使用一个插件帮助完成这些事情,当然也可以自己写逻辑自定义。
之下的逻辑是调用了repositories
方法,然后传递了一个闭包,声明了仓库为Maven中央仓库。
之后就是依赖管理了,相比于Maven,可以看到Gradle的声明运行阶段和依赖包管理更加清晰简洁。
包冲突
在Maven中,处理包冲突有两个规则:1.最近优先。2.最先声明优先。
在Gradle中不同,Gradle是最新版本优先。
自定义Gradle构建
在Gradle中执行任务,如果像传一个参数进去,最好使用的方法是-P
task taska{
doLast{
println "params is $params"
}
}
执行
gradlew taska -Pparams=123
这样就可以直接传递参数给Gradle的运行任务。
另外,我们常常因为Maven的中央仓库下载过慢需要替换镜像。
在在配置路径下,创建文件/.gradle/init.gradle
allprojects{
repositories {
def ALIYUN_REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public'
def ALIYUN_JCENTER_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
all { ArtifactRepository repo ->
if(repo instanceof MavenArtifactRepository){
def url = repo.url.toString()
if (url.startsWith('https://repo1.maven.org/maven2')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
remove repo
}
if (url.startsWith('https://jcenter.bintray.com/')) {
project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
remove repo
}
}
}
maven {
url ALIYUN_REPOSITORY_URL
url ALIYUN_JCENTER_URL
}
}
}
这样就把镜像替换为阿里云镜像,加快速度。
如果在构建中想引用外部的依赖包,可以配置在buildscript {}
中
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.6.RELEASE"
classpath "org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE"
compile('redis.clients:jedis:3.0.1')
}
}
这样就能在执行task
的使用,引用包中的方法。
Gradle的插件
Gradle自定义了插件Api,可以在项目目录下新建文件夹buildSrc
这个文件是约定的。然后创建一个子项目。
在build.gradle
中声明
apply plugin: 'groovy'
dependencies{
compile gradleApi()
}
新建文件MyPlugin.groovy
,导入项目
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyPlugin implements Plugin<Project>{
@Override
void apply(Project project){
project.tasks.create("print"){
doLast{
println (project.name)
}
}
}
}
这样就写了一个简单的Gradle插件,可以在你自己的项目里引用它。在Gradle的约定里,插件也是一段逻辑,所以需要测试来覆盖它。
网友评论