一文让你玩转Gradle
Gradle是一个构建工具,面向开发者的脚本语言是Groovy和Kotlin,简而言之就是我们常用的build.gradle和build.gradle.kts或plugin等。在Gradle中,有大量配置都是通过脚本语言来写的,所以不管是Groovy还是Kotlin,最后的表现都是。
前言
背景介绍
Gradle是一个构建工具,面向开发者的脚本语言是Groovy
和Kotlin
,简而言之就是我们常用的build.gradle和build.gradle.kts或plugin等。
- Groovy:主流语言,新建项目的时候,Groovy是默认的构建脚本语言
- Kotlin:Gradle 5.0之后已经支持
在Gradle中,有大量配置都是通过脚本语言来写的,所以不管是Groovy还是Kotlin,最后的表现都是DSL(Domain Specific Language)
。
Gradle中的DSL
# 声明引入Gradle插件plugin的DSL代码
plugins {
id 'java'
id 'org.springframework.boot' version '2.5.3' apply 'false'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
plugin 有id三个参数配置项:
- id:调用的是PluginDependenciesSpec中的id(String id)函数,返回PluginDependencySpec对象,PluginDependencySpec对象可以理解为是PluginDependenciesSpec的一层封装,
version
和apply
被封装在此对象中 - version:插件的版本号,默认插件无须填写版本号,第三方插件需要填写版本号
- apply:是否将插件应用于当前项目及子项目,默认是
true
,就是就是控制依赖传递的,当不想传递时可以设置为false
Kotlin写法
注意:只介绍引入包一种语法的不同之处
plugins {
id("com.android.application") version "7.3.0" apply false
}
我们可以看出来,其实Kotlin DSL
和Groovy DSL
的写法差别不大,也是调用PluginDependenciesSpec中的id(String id)
函数,只不过差别在调用id(String id)函数时有显式的括号而已。
Gradle安装
下载安装包
从官网下载安装包,然后再本地解压:
配置系统环境变量
GRADLE_HOME:gradle压缩包解压后的目录
GRADLE_USER_HOME:gradle默认的仓库地址 Path:在末尾追加%GRADLE_HOME%/bin
测试
打开CMD命令窗口,输入gradle -v
有如图输出,表示安装成功:
在IDEA内创建Gradle项目
Gradle项目结构
- settings.gradle 配置项目名,模块间的依赖
- build.gradle 配置项目groupId、version、依赖的gradle插件、jar包、jar仓库
- gradle/wrapper/gradle-wrapper.properties 配置当前项目使用的gradle软件版本、及下载目录
- build目录 项目打包的输出目录
编译打包
打开idea右侧的Gradle菜单,Tasks/build子菜单下有一组gradle指令,可以使用jar指令打包项目。打包结果输出在build目录:
Gradle配置国内的源
国内镜像感觉aliyun的比较全,最新地址如下:
developer.aliyun.com/mvn/view
在build.gradle中修改镜像地址配置:
repositories {
maven{ url 'https://maven.aliyun.com/repository/central' }
maven{ url 'https://maven.aliyun.com/repository/public' }
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin'}
}
注意:如果项目中引用了gradle plugin包,必须加入https://maven.aliyun.com/repository/gradle-plugin
,不然在central仓库中找不到。如果有
maven 项目秒变Gradle项目
切到maven项目pom文件所在的目录,然后执行如下命令:
#1.7写法
gradle setupBuild --type pom
#2.0写法
gradle init --type pom
常用SpringBoot Gradle的配置案例
/****************************************
* gradle.properties
* 各dependency的版本
*/
springBootVersion = 2.0.3.RELEASE
springVersion = 5.0.7.RELEASE
protobufPluginVersion = 0.8.6
protobufJavaVersion = 3.6.0
grpcPluginVersion = 1.14.0 # same to grpcVersion
grpcVersion = 1.14.0
guavaVersion = 25.1-jre
mysqlConnectorVersion = 6.0.6
lombokVersion = 1.18.2
/****************************************
* repo配置
* 相关nexus配置参见~/.gradle/gradle.properties: nexus.url nexus.username nexus.password
*/
buildscript {
// repositories for plugins in build script
repositories {
mavenLocal()
maven {
name "nexus"
url property("nexus.url")
credentials {
username property("nexus.username")
password property("nexus.password")
}
}
}
}
// repositories for project dependencies
repositories {
mavenLocal()
maven {
name "nexus"
url property("nexus.url")
credentials {
username property("nexus.username")
password property("nexus.password")
}
}
}
/****************************************
* SpringBoot基本配置
*/
buildscript {
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
// spring 2.+
bootJar.archiveName="${project.name}-boot.jar"
task('release', type: Copy) {
dependsOn bootJar
from("$buildDir/libs/") {
include "${project.bootJar.archiveName}"
}
String date = "date +%Y%m%d".execute().text.trim()
String baseDir = date + "_" + project.version
String defaultDir = "/global/release/${project.name}/$baseDir"
String dir = defaultDir
if (project.hasProperty("dir")) {
dir = project.property("dir")
}
into "$dir"
doLast {
println ". release into: ${project.release.destinationDir}/${project.bootJar.archiveName}"
}
}
/****************************************
* SpringBoot的Configuration Processor
* 并将metadata.json拷贝到resources目录,以便在IDEA中起效
*/
// copy spring-configuration-metadata.json when it's generated
compileJava << {
project.copy {
from("${sourceSets.main.java.outputDir}/META-INF") {
include "*.json"
}
into "src/main/resources/META-INF"
}
}
// 依赖spring-boot-configuration-processor
dependencies {
// gradle 官方推荐的方式
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
// 避免IDEA的警告,不过不加也没关系
compileOnly("org.springframework.boot:spring-boot-configuration-processor")
}
/****************************************
* 常用的java task
*/
task sourcesJar(type: Jar, dependsOn: classes) {
from sourceSets.main.allJava
classifier = 'sources'
doLast {
println archivePath
}
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
doLast {
println archivePath
}
}
/****************************************
* 输出task结果
*/
jar << {
println archivePath
}
test << {
println reports.html.entryPoint
}
jacocoTestReport << {
println reports.html.entryPoint
}
/****************************************
* lombok
*/
dependencies {
// lombok,两种方式依赖都需要
annotationProcessor("org.projectlombok:lombok:$lombokVersion")
compileOnly("org.projectlombok:lombok:$lombokVersion")
}
/****************************************
* proto module的配置
*/
buildscript {
dependencies {
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion"
}
}
apply plugin: "java-library"
apply plugin: "com.google.protobuf"
// protobuf setting
protobuf {
// change generated directory
generatedFilesBaseDir = "$projectDir/gen/"
def userhome = System.properties['user.home']
plugins {
// define a codegen plugin named as `naming`
naming {
path = "$userhome/.protobuf/naming.py"
}
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:$grpcPluginVersion"
}
}
generateProtoTasks {
ofSourceSet('main')
// all() returns the collection of all protoc tasks
all().each { task ->
// Here you can configure the task by name of each codegen plugin
// change output sub-directory to put all generated files together
task.plugins {
naming {
outputSubDir = "java"
}
grpc {
outputSubDir = "java"
}
}
}
}
}
clean {
// remove protobuf generated files when clean
delete protobuf.generatedFilesBaseDir
}
sourceSets {
// add protobuf generated files into sourceSet automatically
main.java.srcDir("${protobuf.generatedFilesBaseDir}/main/java")
}
apply plugin: 'idea'
idea {
module {
// mark protobuf source directory as source root
sourceDirs += sourceSets.main.proto.sourceDirectories
}
}
task('protoZip', type: Zip) {
from sourceSets.main.proto
classifier = 'proto'
doLast {
println archivePath
}
}
// publish proto zip if necessary
afterEvaluate {
project.publishing.publications {
mavenJava(MavenPublication) {
// 发布proto包
artifact protoZip
}
}
}
// protobuf dependencies
dependencies {
// protobuf dependency
api("com.google.protobuf:protobuf-java:$protobufJavaVersion")
// grpc dependencies
api("io.grpc:grpc-protobuf:$grpcVersion")
api("io.grpc:grpc-stub:$grpcVersion")
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)