gradle中task分为生命周期任务和可执行任务,具有配置阶段与执行阶段两大生命周期;其执行遵循dag依赖图,支持惰性注册与dofirst/dolast动作封装。

在 Java 项目中,Gradle 的 tasks 是构建流程的核心抽象。你可以通过定义自定义 task 来控制编译、资源处理、打包、校验等环节,比 Maven 更灵活、更可编程。
理解 Task 的基本类型与生命周期
Gradle 中的 task 分为两类:内置 task(如 compileJava、jar)和自定义 task。每个 task 都有 dependsOn、doFirst、doLast 等关键属性,执行顺序由 DAG(有向无环图)决定。
- task 默认是惰性执行的,只有被显式调用或作为依赖被触发时才运行
- 使用
tasks.register("myTask")(推荐)或task myTask(旧语法)声明 task - 避免直接用
task myTask { ... }定义逻辑体,应优先用doFirst/doLast或独立 action 类封装行为
自定义 Java 编译任务(例如跳过某些源码目录)
Gradle 默认用 JavaCompile task 编译 src/main/java,但你可以覆盖或新增 task 来处理特殊路径,比如编译 src/gen/java 下的代码生成结果:
tasks.register('compileGeneratedJava', JavaCompile) {
source = fileTree('src/gen/java')
classpath = sourceSets.main.output + sourceSets.main.compileClasspath
destinationDirectory = layout.buildDirectory.dir('classes/generated')
options.encoding = 'UTF-8'
}
// 让主编译依赖它
tasks.named('compileJava') {
dependsOn('compileGeneratedJava')
}
这样,执行 ./gradlew build 时会先编译生成代码,再编译主代码,且生成类输出到独立目录,不干扰标准结构。
自定义打包任务(例如生成带时间戳的 fat jar)
Gradle 的 jar task 可以扩展,也可以新建一个专用打包 task。下面是一个生成包含版本号+时间戳的可执行 fat jar 的例子:
import org.gradle.jvm.tasks.Jar
tasks.register('fatJar', Jar) {
archiveClassifier = 'all' // 生成 xxx-all.jar
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar // 合并主 jar 的 manifest 和 classpath
manifest {
attributes 'Main-Class': 'com.example.Main'
attributes 'Build-Time': new Date().format('yyyy-MM-dd HH:mm:ss')
}
archiveFileName = "${project.name}-${project.version}-${new Date().format('yyyyMMdd-HHmm')}-all.jar"
}
执行 ./gradlew fatJar 即可生成带时间戳的完整 jar。注意:若需自动替换默认 jar,可用 tasks.named('jar').configure { ... } 修改其行为。
组合与复用:用 task 串联构建步骤
实际项目常需要多个定制步骤协同。例如:生成代码 → 编译 → 运行静态检查 → 打包 → 上传到本地 repo。可以这样组织:
tasks.register('prepareForRelease') {
dependsOn 'generateProto', 'compileGeneratedJava', 'checkstyleMain'
doLast {
logger.lifecycle "✅ Ready for release packaging"
}
}
tasks.register('publishToLibs') {
dependsOn 'fatJar'
doLast {
copy {
from tasks.named('fatJar').get().archiveFile
into layout.projectDirectory.dir('libs')
}
}
}
这样 ./gradlew publishToLibs 就会自动触发前置链路,无需手动挨个执行。
Gradle 的 task 机制本质是声明式 + 函数式编程模型,重点在于理清输入(inputs)、输出(outputs)、依赖(dependsOn)和动作(doLast)。只要明确每个 task 的职责边界和上下游关系,就能安全、清晰地定制整个 Java 构建流程。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











