Gradle

Gradle

在这里插入图片描述

image-20220705144901749

Gradle 简介

Gradle 是一款Google 推出的基于 JVM、通用灵活的项目构建工具,支持 Maven,JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件,转而使用简洁的支持多种语言(例如:java、groovy 等)的 build 脚本文件

官网地址:

学习Gradle 的原因:

  1. 目前已经有相当一部分公司在逐渐使用Gradle作为项目构建工具了。
  2. 作为Java开发程序员,如果想下载Spring、SpringBoot等Spring家族的源码,基本上基于Gradle构建的。

总之,虽然目前市面上常见的项目构建工具有Ant、Maven、Gradle,主流还是Maven,但是未来趋势Gradle

常见的项目构建工具

Ant: 2000 年 Apache 推出的纯Java 编写构建工具,通过 xml[build.xml]文件管理项目优点:使用灵活,速度快(快于 gradle 和 maven),

缺点:Ant 没有强加任何编码约定的项目目录结构,开发人员需编写繁杂XML 文件构建指令,对开发人员是一个挑战。

Maven: 2004 年Apache 组织推出的再次使用xml 文件[pom.xml]管理项目的构建工具。

优点: 遵循一套约定大于配置的项目目录结构,使用统一的GAV 坐标进行依赖管理,侧重于包管理。缺点:项目构建过程僵化,配置文件编写不够灵活、不方便自定义组件,构建速度慢于 gradle。

Gradle: 2012 年Google 推出的基于Groovy 语言的全新项目构建工具,集合了Ant 和 Maven 各自的优势。

优点:集 Ant 脚本的灵活性+Maven 约定大于配置的项目目录优势,支持多种远程仓库和插件**,侧重于大项目构建**。缺点:学习成本高、资料少、脚本灵活、版本兼容性差等。

劣势:每一个版本都较上一次有非常大的改动,没有做较好向上兼容学习成本高,groovy脚本语言

Whatever:无论哪种项目构建工具,都有自身的优势和劣势,所以选择一款最适合自己的就是最好的。

Gradle是一种开源自动化构建工具,支持多语言环境,受Ant、Maven思想的影响,集二者之大成,相比Ant的不规范,Maven的配置复杂、生命周期限制较多,Gradle既规范也更灵活,可以使用DSL(领域特定语言,如Groovy)编写构建,脚本更加精悍。本课程基于Gradle7讲解。

Gradle、Ant、Maven比较

Gradle组成

1648264920538

Gradle 安装

Gradle 安装说明

Gradle官网:https://gradle.org/

Gradle官方下载安装教程页面:https://gradle.org/install/

Gradle官方用户手册:https://docs.gradle.org/current/userguide/userguide.html

其中SpringBoot 与Gradle 存在版本兼容问题,Gradle 与Idea 也存在兼容问题,所以考虑到 java 程序员会使用SpringBoot,所以要选择 6.8 版本及高于 6.8 版本的Gradle,那么相应的idea 版本也要升级,不能太老哦。

我们找到我们idea的安装目录,我这里可以看出我要安装7.4的版本。

image-20220705195409102

具体参考文档

image-20220705194911051

安装JDK

要求Jdk 为 1.8 或者 1.8 版本以上

下载并解压到指定目录

image-20220705200216336

我这里下的是完整版本

image-20220705200906584

配置环境变量

新建GRADLE_HOME环境变量,变量值为将gradle根目录

image-20220705201433510

在path中加入项%GRADLE_HOME%\bin,类似于JDK或Maven的配置

image-20220705201507116

打开CMD,执行gradle -v,成功输出版本则表示安装配置完成

image-20220705201600350

接着再配置一个GRADLE_USER_HOME环境变量,GRADLE_USER_HOME 相当于配置Gradle 本地仓库位置和 Gradle Wrapper 缓存目录

只能叫GRADLE_USER_HOME,Gradle本地仓库可以和Maven本地仓库目录一致,我这里就选择maven本地的仓库目录了

image-20220705202216789

Gradle更换阿里镜像源

Gradle 自带的Maven 源地址是国外的,该Maven 源在国内的访问速度是很慢的,除非使用了特别的手段。一般情况下,我们建议使用国内的第三方开放的Maven 源或企业内部自建Maven 源。

在我们下载的gradle目录下的init.d文件夹下有一个readme.txt的文件

image-20220706095521904

内容如下:

image-20220706095802226

所以我们在init.d 文件夹创建init.gradle 文件,内容如下

其中mavenLocal()表示会先使用本地仓库(前提是配置了M2_HOME环境变量),没有的话就执行下面指定仓库的地址查找。

image-20220706100546431

allprojects {
    repositories {
        mavenLocal()
        maven { name "AlibabaCentral" ; url "https://maven.aliyun.com/repository/central" } 
        maven { name "AlibabaPublic" ; url "https://maven.aliyun.com/repository/public" } 
        maven { name "AlibabaGoogle" ; url "https://maven.aliyun.com/repository/google" } 
        maven { name "AlibabaGradlePlugin" ; url "https://maven.aliyun.com/repository/gradle-plugin" } 
        maven { name "AlibabaSpring" ; url "https://maven.aliyun.com/repository/spring" } 
        maven { name "AlibabaCentral" ; url "https://maven.aliyun.com/repository/public" } 
        maven { name "Bstek" ; url "https://nexus.bsdn.org/content/groups/public/" } 
        mavenCentral()
    }
    
    buildscript {
        repositories {
             maven { name "AlibabaCentral" ; url "https://maven.aliyun.com/repository/central" } 
             maven { name "AlibabaPublic" ; url "https://maven.aliyun.com/repository/public" } 
             maven { name "AlibabaGoogle" ; url "https://maven.aliyun.com/repository/google" } 
             maven { name "AlibabaGradlePlugin" ; url "https://maven.aliyun.com/repository/gradle-plugin" } 
             maven { name "AlibabaSpring" ; url "https://maven.aliyun.com/repository/spring" } 
             maven { name "AlibabaCentral" ; url "https://maven.aliyun.com/repository/public" } 
             maven { name "Bstek" ; url "https://nexus.bsdn.org/content/groups/public/" } 
             maven { name "M2" ; url 'https://plugins.gradle.org/m2/' }
        }
    }
}

拓展 1:启用init.gradle 文件的方法有:

1.在命令行指定文件,例如:gradle --init-script yourdir/init.gradle -q taskName。你可以多次输入此命令来指定多个init文件

2.把init.gradle文件放到 USER_HOME/.gradle/ 目录下

image-20220706101148689

3.把以.gradle结尾的文件放到 USER_HOME/.gradle/init.d/ 目录下

4.以.gradle结尾的文件放到 GRADLE_HOME/init.d/ 目录下

如果存在上面的4种方式的2种以上,gradle会按上面的1-4序号依次执行这些文件,如果给定目录下存在多个init脚本,会按拼音a-z顺序执行这些脚本,每个init脚本都存在一个对应的gradle实例,你在这个文件中调用的所有方法和属性,都会委托给这个gradle实例,每个init脚本都实现了Script接口。

拓展 2:仓库地址说明

mavenLocal(): 指定使用maven本地仓库,而本地仓库在配置maven时settings文件指定的仓库位置。如D:/repository,gradle 查找jar包顺序如下:USER_HOME/.m2/settings.xml >> M2_HOME/conf/settings.xml >> USER_HOME/.m2/repository

maven { url 地址},指定maven仓库,一般用私有仓库地址或其它的第三方库【比如阿里镜像仓库地址】。

mavenCentral():这是Maven的中央仓库,无需配置,直接声明就可以使用。

jcenter():JCenter中央仓库,实际也是是用的maven搭建的,但相比Maven仓库更友好,通过CDN分发,并且支持https访问,在新版本中已经废弃了,替换为了mavenCentral()。

总之, gradle可以通过指定仓库地址为本地maven仓库地址和远程仓库地址相结合的方式,避免每次都会去远程仓库下载依赖库。这种方式也有一定的问题,如果本地maven仓库有这个依赖,就会从直接加载本地依赖,如果本地仓库没有该依赖,那么还是会从远程下载。但是下载的jar不是存储在本地maven仓库中,而是放在自己的缓存目录中,默认在USER_HOME/.gradle/caches目录,当然如果我们配置过GRADLE_USER_HOME环境变量,则会放在GRADLE_USER_HOME/caches目录,那么可不可以将gradle caches指向maven repository。我们说这是不行的,caches下载文件不是按照maven仓库中存放的方式。

拓展 3:阿里云仓库地址请参考:https://developer.aliyun.com/mvn/guide

image-20220706100805361

Gradle 项目目录结构

Gradle 项目默认目录结构和Maven 项目的目录结构一致,都是基于约定大于配置【Convention Over Configuration】。其完整项目目录结构如下所示:

img

Tips:

  1. 只有war工程才有webapp目录,对于普通的jar工程并没有webapp目录
  2. gradlew与gradlew.bat执行的是指定wrapper版本中的gradle指令,不是本地安装的gradle指令哦。

Gradle 创建第一个项目

借助于 spring 脚手架创建gradle 第一个项目:https://start.spring.io/

image-20220706082552926

项目内容如下:

image-20220706085144385

# distributionBase和distributionPath是配合使用,指定gradle解压后的存放位置
# GRADLE_USER_HOME表示用户目录,
	# windows系统:c:\window\<user-name>\.gradle\
	# linux是$HOME/.gradle
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# 指定某个版本gradle下载地址,idea插件中规定的版本
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
# zipStoreBase和zipStorePath配合使用,指定下载gradle.zip存放位置
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

修改gradle的配置项

image-20220706085100362

这就是依赖项

image-20220706085707982

添加依赖:

image-20220706104618865

特别提示 1:使得在Terminal 中执行以gradlew 开头命令和操作图形化的IDEA 使用Gradle 版本不一定是同一个版本

1.Terminal中以gradlew开头指令用的是Wrapper规定的gradle版本,wrapper中规定版本默认和idea插件中规定的版本一致。

2.而图形化的IDEA使用Gradle是本地安装的哦。

特别提示 2:目前只能是在创建项目时重新设置本地gradle,创建新项目需要重新去改。不像maven可以在创建项目之前就可以默认项目配置

特别提示3:当 我 们 在 gradle.build 文 件 添 加 依 赖 之 后 , 这 些 依 赖 会 在 下 载 到GRADLE_USER_HOME/caches/modules-2/files-2.1 目录下面,所以这里的 GRADLE_USER_HOME 相当于 Gradle 的本地仓库,当然也可以如下方式找到jar 包位置。

image-20220706110829995

image-20220706110948987

Gradle 中的常用指令

常用gradle指令作用
gradle clean清空build目录
gradle classes编译业务代码和配置文件
gradle test编译测试代码,生成测试报告
gradle build构建项目
gradle build -x test跳过测试构建项目

需要注意的是:gradle 的指令要在含有build.gradle 的目录执行

Gradle内置方法

常用的Project方法

方法描述
afterEvaluate可以添加一个闭包,它会在项目完成评估后立即执行。当执行属于该项目的构建文件时,会通知此类监听器。
allprojects配置当前项目以及它的每个子项目
apply应用零个或多个插件或脚本。
beforeEvaluate添加一个闭包,它会在项目开始评估前立即执行
configure通过闭包配置对象集合。
copy复制指定的文件
defaultTasks设置此项目的默认任务的名称。当开始构建时没有提供任务名称时使用这些。
delete删除文件和目录
exec执行外部命令
file解析相对于该项目的项目目录的文件路径
findProject按路径定位项目。如果路径是相对的,则相对于该项目进行解释。
findProperty找特定属性,如果未找到,则返回给定属性的值或 null
getAllTasks返回此项目中包含的任务的地图
hasProperty确定此项目是否具有给定的属性
javaexec执行 Java 主类
javaexec执行外部 Java 进程。
mkdir创建一个目录并返回一个指向它的文件。
property返回给定属性的值。此方法定位属性如下:
setProperty设置此项目的属性。此方法在以下位置搜索具有给定名称的属性,并将该属性设置在它找到该属性的第一个位置。
subprojects配置本项目的子项目
task创建Task具有给定名称的 a 并将其添加到此项目中
uri将文件路径解析为 URI,相对于该项目的项目目录

常用方法示例

这是用gradle创建的springboot工程的第一种示例:

这种是在我们idea默认的配置项

plugins {
    //维护springboot的版本号,不单独使用,和下面的俩个插件一起使用
    id 'org.springframework.boot' version '2.7.1'
    //类似于maven中的<dependencyManagement/>只做依赖的管理,不做实际依赖
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.zsq'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    //我们前面的插件指定了默认的版本号,做了版本管理,所以我们这可以不用写版本号
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'cn.hutool:hutool-all:5.8.4'
}

tasks.named('test') {
    useJUnitPlatform()
}

这是用gradle创建的springboot工程的第二种示例:

buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/public' }
    }

    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.7.1'
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'


group = 'com.zsq'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    //我们前面的插件指定了默认的版本号,做了版本管理,所以我们这可以不用写版本号
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'cn.hutool:hutool-all:5.8.4'
}

tasks.named('test') {
    useJUnitPlatform()
}

1.buildscript{}:配置当前gradle脚本自身需要使用的构建信息或依赖
buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/public' }
    }

    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.7.1'
    }
}
2.repositories{}:仓库配置

通过 repositories{} 可以配置maven,ivy,local仓库。这样子,在dependencies{}声明的依赖就可以通过repositories{}中指定的仓库查询到具体的JAR资源。

repositories {
	mavenLocal()
	mavenCentral()
	maven {
		// Name is optional. If not set url property is used
		name = 'Main Maven repository'
		url = 'https://maven.aliyun.com/repository/central'
	}

	//有权限控制的仓库
	maven() {
		credentials {
			username = 'username'
			password = 'password'
		}
		url = 'https://maven.aliyun.com/repository/central'
	}

	//本地仓库
	repositories {
		flatDir(dir: '../lib', name: 'libs directory')
		flatDir {
			dirs '../project-files', '/volumes/shared-libs'
			name = 'All dependency directories'
		}
	}
}
3.dependencies{}:依赖配置

在gradle中dependencies{}是一等公民,它描述了configurations{}中分组依赖的第三方资源。我们可以把依赖简单的分成两大类:

  1. gradle依赖:主要是gradle运行的时候,需要加载一些插件,如android等,此时需要配置它。
  2. 项目编译/运行依赖:编译一个项目,通常需要依赖其他项目或者JAR。
  3. 依赖的常规写法(与maven一致)

下载

//配置依赖
dependencies {
    //compile已过时,推荐使用implementation
	//按照maven名称加载jar
   implementation 'com.google.guava:guava:11.0.2'
    //排除部分依赖
    implementation('org.slf4j:slf4j-simple:1.6.4') {
		exclude 'org.slf4j:slf4j-api'
	}
    //测试模块
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
    
    //依赖其他子项目
    implementation project(':projectA')
	//加载目录下所有的jar
	implementation fileTree(dir: 'libs', include: ['*.jar'])  //多个文件
    
    implementation ('com.google.guava:guava:11.0.2'){
        //在版本冲突的情况下优先使用该版本
        isForce = true
        //禁用依赖传递
        transitive = false
    }
}
//使用dependencis任务可以查看当前依赖树,*表示被忽略的

工程化之插件

获取插件的渠道有以下2种

  • 访问Gradle插件官网
  • Github搜索,有一些插件并没有被官方所收录,但仍然能够使用,但需要承担一些隐藏的风险

现如今使用评率非常高的几款插件:SpringBoot构建插件,Docker容器集成插件,junit单元测试插件等

Gradle 有两种插件

脚本插件script plugins

脚本插件通常是一个脚本,和一个普通的 build.gradle 文件没什么区别 。脚本插件其实并不能算是一个真正的插件,就是一个扩展脚本。但我们不能忽视它的作用,它是脚本模块化的基础。我们可以把复杂的脚本文件,进行分块,分段整理,拆分成一个个职责分明的脚本插件。就像我们平常封装的 Utils 工具类一样,封装一个 utils.gradle 工具脚本。脚本可以存在本地,也可以存在网络上,只需要提供脚本的相对路径或者 URL ,引用方式如下:

//使用本地插件
apply from: './other.gradle'
apply from: this.rootProject.file('other.gradle')

//使用网络远程插件
apply from: 'https://gitee.com/xxx/xx/raw/master/it235.gradle' 
二进制插件binary plugins

我们可以通过二进制插件的ID来应用。插件 ID 是插件的全局唯一标识符或者名字。Gradle中的插件按照来源可以分为核心插件和非核心插件。Gradle 核心插件的特殊之处就在于他们都有一个简短的 ID,例如 Java 插件的是 “java” 。其它非核心二进制插件也必须使用插件ID的完全限定形式(例com.github.foo.bar)。使用二进制插件的方式有2种,如下。

  • 必须结合buildscript{} 应用插件 ,老版本中使用

    //build.gradle中的顶级语句,如下分别是使用java/idea/war/docker插件
    apply plugin: 'java'
    //apply plugin: JavaPlugin 也可以通过指定插件类来应用,与java效果一样
    apply plugin: 'idea'
    apply plugin: "war"
    //声明
    apply plugin: "com.jfrog.bintray"
    apply plugin: 'org.akhikhl.gretty'
    
    //buildscript
    buildscript {
      repositories {
        maven {url "https://maven.aliyun.com/repository/public"}
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
      }
      //应用插件
      dependencies {
        classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0"
        classpath 'org.akhikhl.gretty:gretty:+'
      }
    }
    
  • plugins{} 新写法,这种叫plugins DSL写法,对应的是PluginDependenciesSpec实例

    //build.gradle中的顶级语句,声明和应用放在一起
    plugins {
        //核心插件,gradle提供
        id 'java'
        id 'eclipse'
        id 'war'
        //非核心插件(社区插件),必须通过id+version的全限定名的方式进行引用
        id 'com.bmuschko.docker-remote-api' version '6.7.0'
        //apply false 表示在父项目中声明,但是父项目不会立即加载,可以在子项目中通过ID的方式进行使用
        id 'com.jfrog.bintray' version '1.8.5' apply false
    }
    //注意:plugins暂时不支持第三方插件,如果要使用第三方插件请使用老的写法。同时plugins中不能随意编写其他的语句体
    
    • apply false的使用场景

      //settings.gradle,有3个子项目
      include 'hello-a'
      include 'hello-b'
      include 'goodbye-c'
      
      //根项目的build.gradle
      plugins {
          //apply false 表示根项目不会解析加载,只进行定义和插件的版本管理
          id 'com.example.hello' version '1.0.0' apply false
          id 'com.example.goodbye' version '1.0.0' apply false
      }
      
      //hello-a/build.gradle
      plugins {
          id 'com.example.hello'
      }
      
      //hello-b/build.gradle
      plugins {
          id 'com.example.hello'
      }
      
      //goodbye-c/build.gradle
      plugins {
          id 'com.example.goodbye'
      }
      
  • 自定义插件

    插件自定义包括三个步骤:建立插件工程、配置参数、发布插件与使用插件。

    插件的源码可以存放在以下3个地方

    • build script中

      可以直接在build.gradle中编写插件,这样的好处是当前项目能够自动编译和加载,但该插件在构建脚本之外不可见。

      class GreetingPlugin implements Plugin<Project> {
          void apply(Project project) {
              project.task('hello') {
                  doLast {
                      println 'Hello from the GreetingPlugin'
                  }
              }
          }
      }
      // Apply the plugin
      apply plugin: GreetingPlugin
      //使用 gradle -q hello 执行即可
      
    • buildSrc project中

      您可以将插件的源代码放在以下目录中(不同语言编写用不同的目录)

      • rootProjectDir/buildSrc/src/main/java
      • rootProjectDir/buildSrc/src/main/groovy
      • rootProjectDir/buildSrc/src/main/kotlin

      Gradle 将负责编译和测试插件,并使其在构建脚本的类路径中可用。该插件对构建使用的每个构建脚本都是可见的。但是,它在构建之外是不可见的,因此您不能在定义它的构建之外重用插件。

    • 独立项目中

      创建一个单独的项目。该项目生成并发布一个 JAR,然后就可以在多个项目中使用该插件,其他开发者也能下载使用。我们一般会在该jar中编写或依赖一些插件,或者将几个相关的任务类捆绑到一起。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值