Gradle使用笔记

20210320-Gradle使用笔记

安装和环境配置

Mac的安装和使用

终端命令查看gradle版本

gradle -v
#####效果
albertdale@albertdaledeMacBook-Pro config % gradle -v

------------------------------------------------------------
Gradle 6.8
------------------------------------------------------------

Build time:   2021-01-08 16:38:46 UTC
Revision:     b7e82460c5373e194fb478a998c4fcfe7da53a7e

Kotlin:       1.4.20
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          1.8.0_212 (Oracle Corporation 25.212-b10)
OS:           Mac OS X 10.16 x86_64

build.gradle文件的配置

mavenLocal()的配置

  1. mavenLocal()表示使用本地maven仓库
  2. mavenCentral()使用maven中心仓库
  3. 使用阿里云(maven {url 'http://maven.aliyun.com/nexus/content/groups/public/'})#这个相当于使用自定义maven仓库地址的配置,可以是私服。
  4. JCenter是Goovy Grape内的默认仓库,Gradle内建支持jcenter()仓库,项目库打包成aar文件类似jar,只是多了res,lib文件的包,上传到jcenter后,可以很方面的在本地调用库文件
repositories {
       mavenLocal()
        google()
        jcenter()
    maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
    }
    ###Gradle使用mavenLocal()以及自定义jar包缓存路径
    经过一番资料查找,发现使用mavenLocal() 时Gradle默认会按以下顺序去查找本地的maven仓库:USER_HOME/.m2/settings.xml >> M2_HOME/conf/settings.xml >> USER_HOME/.m2/repository。注意,环境变量要加入M2_HOME, 我们配环境时很多时候都是使用MAVEN_HOME或者直接在path中输入bin路径了,导致mavenLocal无法生效。

另外,如果本地没有相关jar包,gradle会在下载到USER_HOME/.gradle文件夹下,若想让gradle下载到指定文件夹,配置GRADLE_USER_HOME环境变量

gradle默认本地依赖存储位置

  1. 因为Gradle如果不配置环境变量,则会在用户目录下(在Windows下是C盘的目录)创建.gradle目录,并将下载的依赖文件保存在这个目录里。如果不想使用缺省目录,则可以设置环境变量GRADLE_USER_HOME的路径,就可改变gradle的缓存目录。

Grovvy简单语法

Groovy 是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。

Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使 Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。 [1]

Gradle依赖详解——不同类型的library引入方案

1.本地Module library依赖

//module需要在项目根目录下的settings.gradle中通过include引入
implementation project(':librarydict')

2.本地二进制library依赖:jar和aar

本地的jar和aar需要放在module的libs文件夹下,通过这种方式依赖的弊端时不知道jar和aar的版本号,如果要按照这种方式依赖,建议将jar/aar的名字加上版本信息,方便确认版本
依赖jar:
//可以一条依赖引入libs下所有的jar
implementation fileTree(dir:'libs',include:['*.jar'])

//也可以指定依赖某一个或几个jar
implementation files('libs/dict-v120.jar','libs/download-v151.jar') 
  1. 引入远程maven仓库

//依赖明确的版本,标明group、name和version
implementation group:'con.android.demo',name:'library-dict',version:'1.2.0'

//通常按照如下方式简写即可
implementation 'com.android.demo:library-dict:1.2.0'

//也可以不知道版本,将version改为"+",当远程仓库有更新的版本后,构建时会拉取最新的版本。
//好处是可以始终依赖最新的library:弊端是有可能library的改动导致编译不过或者功能变更不稳定,因为每次都需要检查是否有最新版本,所以构建效率会低一些
implementation 'com.android.demo:library-dict:+'

build.gradle引入Library的几种方式

settings.gradle

  1. build.gradle - 文件包含项目构建所使用的脚本。

  2. settings.gradle - 文件将包含必要的一些设置,例如,任务或项目之间的依懒关系等

  3. settings.gradles是模块Module配置文件,大多数setting.gradle的作用是为了配置子模块,
    根目录下的setting.gradle脚本文件是针对module的全局配置
    
    settings.gradle用于创建多Project的Gradle项目。Project在IDEA里对应Module模块。
    
    例如配置module名rootProject.name = 'project-root',为指定父模块的名称,
    include 'hello' 为指定包含哪些子模块
    
    

简单的groovy 语言

// 介绍grovvy编程语言
println("hello grovvy");
println "hello grovvy"  // grovvy中可以省略括号和语句末尾的分号

// 定义变量
// def是弱类型的,grovvy会自动根据情况来给变量赋予对应的类型
def i = 18
println i
def s = "one fine"
println s

// 复杂类型的定义
def list = ['a', 'b', 'c']  // 集合类型定义
println list  // [a, b, c]
list << 'd'// 往集合中添加元素
println list  // [a, b, c, d]
println list.get(3)  // d  // 取出list中第4个元素

def map = ['k1' : 'v1', 'k2' : 'v2']  // map类型定义
println map  // [k1:v1, k2:v2]
map.k3 = 'v3' // 向map中添加键值对
println map  // [k1:v1, k2:v2, k3:v3]
println map.k3  // v3  // 打印k3的值
println map.get("k3")  // 另一种方式
// grovvy中的闭包
// 闭包其实就是一段代码块,在gradle中,主要是把闭包当参数来使用的

// 定义一个闭包
def b1 = {
    println 'hello b1'
}

// 定义一个方法,参数类型是闭包,不要导包!!!
def method(Closure closure) {
    closure()
}

// 调用method()方法
method(b1)

基于POM,自动生成Gradle配置

  1. Gradle官方非常贴心的内置了插件,可以一键将Maven POM转换为Gradle配置。只需要在项目目录内执行,(pom所在的文件夹路径下执行,就会自动生成build.gradle)
  2. 然后,按照提示,将该Maven项目转换为一个Gradle项目即可。Gradle会自动为我们生成根项目的build.gradle、settings.gradle和gradle wrapper文件夹,当然,还有每个子项目的build.gradle文件(太强大了,笔芯Gradle♥️)
gradle init
##结果
Found a Maven build. Generate a Gradle build from this? (default: yes) [yes, no] yes

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1


> Task :init
Maven to Gradle conversion is an incubating feature.
Get more help with your project: https://docs.gradle.org/6.8/userguide/migrating_from_maven.html

BUILD SUCCESSFUL in 10s
##其中会有两个选项,选择是是否生成gradle项目,然后 选择build的脚本语言

Gradle之多项目构建

  1. Gradle对构建模块化项目提供了强大的支持,在Gradle中每一个模块都是一个项目,称之为Gradle多项目构建技术,多项目构建实现了项目模块化,降低代码耦合度,增加内聚性。
  2. 组装多项目构建:Gradle整个项目是由一个根目录和多个模块的子目录构成,在根目录下新建build.gradle构建脚本,使用gradle projects命令查看所有参与构建的项目:

settings.gradle

settings.gradle 是负责配置项目的脚本
对应 Settings 类,gradle 构建过程中,会根据 settings.gradle 生成 Settings 的对象
对应的可调用的方法在文档里可以查找
其中几个主要的方法有:

  • include(projectPaths)
  • includeFlat(projectNames)
  • project(projectDir)

一般在项目里见到的引用子模块的方法,就是使用 include,这样引用,子模块位于根项目的下一级

#如果想指定子模块的位置,可以使用 project 方法获取 Project 对象,设置其 projectDir 参数
include ':app'
project(':app').projectDir = new File('./app')

build.gradle文件介绍

gradle官方介绍dsl语句

一个项目中只放置一个build.gradle,build.gradle可以理解为一个Project框架,提供了对一个项目的基本配置。

build.gradle 负责整体项目的一些配置,对应的是 Project
gradle 构建的时候,会根据 build.gradle 生成 Project 对象,所以在 build.gradle 里写的 dsl,其实都是 Project 接口的一些方法,Project 其实是一个接口,真正的实现类是 DefaultProject
build.gradle 里可以调用的方法在 Project 可以查到
其中几个主要方法有:

  • buildscript // 配置脚本的 classpath
  • allprojects // 配置项目及其子项目
  • respositories // 配置仓库地址,后面的依赖都会去这里配置的地址查找
  • dependencies // 配置项目的依赖

project的常用属性:

名称 描述
group
name(artifact)
version 项目版本(全局的)
sourceCompatibility = 1.8 // source使用的jdk版本
targetCompatibility = 1.8 // 编译时使用的jdk版本或者更新的java虚拟机兼容
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
dependencies 填写依赖
plugins {
    id 'java' // 当前运行环境是java
}  // 等价:apply plugin: 'java'
# java插件:会自动在构建时打包成可执行的jar,Java plugin插件提供了一系列的任务支持构建、编译、测试Java项目。
group 'top.onefine' //定义项目版本地址
version '1.0-SNAPSHOT' //项目版本号

sourceCompatibility = 1.8  // java版本

/**
 * gradle工程所有jar包的坐标在dependencies属性内放置
 * 		每一个jar包的坐标都有三个基本元素组成:group,name,version
 *
 * testCompile:该属性为jar包的作用域,表示该jar包在测试的时候起作用;
 * 		在gradle中添加坐标的时候,都要带上jar包的作用域
 */
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    // https://mvnrepository.com/artifact/org.projectlombok/lombok
    compile group: 'org.projectlombok', name: 'lombok', version: '1.18.12'
    annotationProcessor 'org.projectlombok:lombok:1.18.12'
    // https://mvnrepository.com/artifact/org.springframework/spring-context
    compile group: 'org.springframework', name: 'spring-context', version: '5.2.5.RELEASE'
}


###### gradle的插件
##Spring Boot - Gradle Plugin
buildscript {
    repositories {
        maven { url 'https://repo.spring.io/libs-milestone' }
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.M2'
    }
}
apply plugin: 'org.springframework.boot'


####org.springframework.boot插件: 用来执行Spring Boot相关任务的,我们熟悉的bootRun和bootJar任务都是从这个插件来的
####io.spring.dependency-management插件
Spring Boot的插件会自动地从你使用的Spring Boot版本里导入spring-boot-dependencies bom,允许你在声明依赖的时候忽略掉版本号,使用这项功能,只需要正常的声明依赖,不用写版本号。

gradle多模块构建参考1

Gradle 插件(Plugins)

  1. plugin采用groovy语言来编写

Gradle 也可以用下面的方式声明使用的插件:

// build.gradle
plugins {
    id 'com.example.plugin', version '1.0'
}
其实是从 Gradle 官方的插件仓库 https://plugins.gradle.org/m2/ 下载的。

当然引用插件之前,需要加载驱动,即是 buildScrip中包含的代码,如下

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
    }
}
 
以上引用了 maven库 jcenter() 依赖了 gradle 2.3 ;因此如果引入自定义的plugin则首选需要加载自定义的驱动进来,后续会详解。 

“plugins {}”块导入的是Gradle官方插件仓库里的插件。如果使用“buildscript {}”块指定第三方库作为Gradle插件的话,指定插件就需要使用“apply plugin”了。

刚刚翻了翻文档,“apply plugin”本身似乎还有更多的用途,而“plugins {}”块似乎是一个新引入的还不足够稳定的特性。题主想要知道更多的话直接看看文档就行了。

gradle-plugins官方教程

实现自定义的插件

  1. 在我们构建项目的 build.gradle 脚本中直接编写,这种方式的好处是插件会自动被编译加载到我们的 classpath 中,我们不需要额外做任何的事情,但是它有很明显的局限性,就是除了在包括它的脚本外别的地方无法复用。
  2. 在我们构建项目的rootProjectDir/buildSrc/src/main/groovy 目录下编写,Gradle 会自动编译到当前项目的classpath中,该项目下所有编译脚本都可以使用该插件,但是除了当前项目之外的都无法复用。
  3. 以单独的工程方式编写,这个工程最终编译发布为一个 JAR 包,它可以在多个项目或不同的团队中共享使用。

常用的社区插件

org.springframework.boot
#grooy模式
plugins {
  id "org.springframework.boot" version "2.4.3"
}
#kotlin
kotlin
plugins {
  id("org.springframework.boot") version "2.4.3"
}

父子项目

buildscript

buildscript buildscript中的声明是gradle脚本自身需要使用的资源.可以声明的资源包括依赖项、第三方插件、maven仓库地址等

group 项目的组

version 版本

name 名称

dependencies

名称 描述
implementation 正常依赖
testImplementation 测试依赖
Provided Provided是对所有的build type以及favlors只在编译时使用
providedRuntime providedRuntime('org.springframework.boot:spring-boot-starter-tomcat'),表示代码在运行时需要的依赖,providedRuntime是指依赖的Jar包不会被加到War包里面
compile
compileOnly
annotationProcessor

implementation、compile、api的区别

  1. implementation不可以传递依赖,但是compile可以传递依赖。
  2. api和compile关键字作用效果是一样的,使用时可以互相替换。实际上,api关键字是用来替代compile关键字的,因为compile关键字将来会被弃用。在高版本的gradle,使用compile关键字会报错并提示使用api关键字代替
  3. api或compile关键字引用的包对于其他module来说是可见的,而implementation关键字引用的包对于其他module来说是不可见的。****api或compile关键字引用的包对于其他module来说是可见的,而implementation关键字引用的包对于其他module来说是不可见的。

gradle 解决冲突忽略文件

implementation ('com.albertdale:myjdbc:1.0-SNAPSHOT') {
        exclude group: 'org.projectlombok'
        exclude module: 'lombok'
    }
    
    #忽略日志文件slf4j
    implementation ('org.apache.zookeeper:zookeeper:3.5.5') {
        exclude group: 'org.slf4j'
        exclude module: 'slf4j-log4j12'
    }

依赖本地文件:

Gradle依赖之‘五种依赖配置’

compile fileTree

Gradle的传递性依赖特性

compile("org.springframework:spring-web:4.3.4.RELEASE") {
    transitive = false
}
implementation 表示依赖,即 只依赖不打包进来。
  api 表示打包,即 不仅依赖还打包进来,这样上层就不用重复依赖。
  #annotationProcessor和kapt
  APT(Annotation Processing Tool),即注解处理工具,在代码编译期对源代码进行扫描,找出代码中的注解,根据开发者定义的解析规则生成新的Java文件,新生成的Java文件最终也会生成class文件。APT处理流程如下:
  Kotlin中不使用annotationProcessor,而是使用kapt,其使用方式为
 compile fileTree(dir: 'libs', include: '*.jar')
   provided fileTree(dir: '../honjane-demo-library/libs', include: '*.jar')
   compile(name: 'lib-1.1', ext: 'aar')//依赖并执行本地aar包

依赖远程文件:

  compile "com.jakewharton:butterknife:8.2.1"
  provided 'com.android.support:support-annotations:23.2.1'

依赖库工程(多module):

 compile project(':honjane-demo-library')

gradle命令查看版本号

gradle -version
----------------结果
------------------------------------------------------------
Gradle 6.8
------------------------------------------------------------

Build time:   2021-01-08 16:38:46 UTC
Revision:     b7e82460c5373e194fb478a998c4fcfe7da53a7e

Kotlin:       1.4.20
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          1.8.0_212 (Oracle Corporation 25.212-b10)
OS:           Mac OS X 10.16 x86_64

gradle的本地仓库配置

  • 让 gradle 使用本地 maven 仓库

如上面 build.gradle 文件所示,gradle 默认使用的是 maven 中央仓库,添加 jar 包时,会从 maven 中央仓库下载 jar 包到指定目录(Mac 下是 /Users/用户名/.gradle)。

如果想使用本地的 maven仓库,可以指定环境变量 GRADLE_USER_HOME 为 本地 maven 仓库的路径,然后在 build.gradle 中添加 mavenLocal(),如下:

img

image.png

repositories {
    maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
    mavenLocal()
    mavenCentral()
}

以上表示,先从本地仓库寻找 jar 包,若找不到,再从中央仓库下载.

使用gradle命令行创建一个Java项目

  1. 新建一个文件夹,即为项目文件夹,然后创建一个文件。 build.gradle

  2. build.gradle是Gradle的配置文件

  3. //(apply plugin: 'java'作用是引入java插件),但是其背后已经帮我们做了很多事情,比如它使得我们能够运行gradle build命令。这里的build即为Gradle中的一个任务(Task),我们还可以运行以下命令查看到更多的Task。
    apply plugin: 'java'
    
    task "create-dirs"  {
    
       sourceSets*.java.srcDirs*.each { it.mkdirs() }
    
       sourceSets*.resources.srcDirs*.each { it.mkdirs() }
    
    }
    
  4. 执行命令

  5. gradle create-dirs
    

    然后就生成了项目。

gradle其实就是在maven的基础上简化了pom配置,使用简洁的风格,不用写很长的xml文件。
gradle使用task的方式执行任务,一个操作由多个task共同完成,清晰的展现在日志中。

gradle启动脚本

gradle通过调用一个名字叫gradlew的脚本然后加载了gradle-wrapper.jar最终才开始执行gradle命令。

使用Gradle Wrapper

对于所有的Gradle项目来说,笔者都推荐使用Gradle Wrapper,甚至应该将其当做创建代码库之后的第一件事来做。使用Gradle Wrapper有以下好处:

  1. 不用安装gradle也能运行gradle
  2. 所有人使用相同的gradle版本

在build.gradle中加入以下配置:

task wrapper(type: Wrapper) {
    gradleVersion = '3.0'
}

然后在命令行运行:

gradle wrapper

此时会生成以下三个文件(夹):gradlew、gradlew.bat和gradle目录。

这里的gradlew和gradlew.bat其实只是脚本文件(前者用于Unix/Linux/Mac,后者用于Windows),在使用gradle命令的地方替换为gradlew或gradlew.bat,他们将自动下载指定的gradle版本,然后用该版本进行项目构建。如上文所示,本文中我们配置gradle版本为3.0。

请注意,这三个文件(夹)都需要提交到代码库中。当项目其他人拿到代码之后,由于gradlew和gradlew.bat文件均在源代码中,他们本地即便没有gradle,依然可以通过以下命令进行项目构建:

./gradlew build

如果你的项目有持续集成(CI)服务器(你也应该有),那么你的CI机器也没有必要安装Gradle了。另外,此时所有人都是使用的相同版本的gradle,进而避免了由于版本不同所带来的问题。

setting.gradle

settings文件介绍:使用过Gradle构建项目的都应该知道这个文件,该文件声明了项目层次结构所需的配置。默认情况下,这个文件被命名为settings.gradle,并且和根项目的build.gradle文件放在一起。简单配置settings.gradle文件

//settings.gradle脚本:
include 'model'
include 'repository', 'web'
 
//再次运行gradle projects命令,可以看出多了3个子项目:
> Task :projects 
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'root'
+--- Project ':model'
+--- Project ':repository'
\--- Project ':web'

gradle常用的函数

//建立函数copyJar 用于把依赖的jar复制到对应的目录下
task copyJar(type:Copy){
    from configurations.runtime
    into ('build/libs/lib')

}

gradle的一些异常信息处理

IDEA + Gradle项目lombok不生效问题
#加上
compile(group: 'org.projectlombok', name: 'lombok', version: '1.16.10')
annotationProcessor 'org.projectlombok:lombok'
#或者
 annotationProcessor 'org.projectlombok:lombok:1.18.2'

参考链接1

参考链接2

参考链接3

Mac系统默认下载到:C:/Users/(用户名)/.gradle/caches/modules-2/files-2.1

Windows系统默认下载到:C:\Users(用户名).gradle\caches\modules-2\files-2.1

可以看到,默认是在C盘里,但是有的人可能有强迫症或者特殊要求,需要更改这个默认路径,

更改Gradle下载的依赖jar包路径位置

1、配置环境变量

添加变量GRADLE_USER_HOME,值为gradle依赖下载存放路径

img

2、在IDEA下手动配置依赖下载路径

对于IDEA来说没有用(当然上面的环境变量还是要添加的),在IDEA中使用gradle需要修改下面的路径

img

浏览量: 4,142

gradle打包项目成jar包

jar {
    //详细信息参考 https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html
    archivesBaseName = 'BaseClient'//基本的文件名
    archiveVersion = '0.0.3' //版本
    manifest { //配置jar文件的manifest
        attributes(
                "Manifest-Version": 1.0,
                'Main-Class': 'com.albertdale.client.baseclient.BaseClientMainApplication' //指定main方法所在的文件
        )
    }
    //打包依赖包
    from {
        (configurations.runtimeClasspath).collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
}

images

gradle install项目到maven本地和远程仓库

引用插件
 apply plugin: 'maven-publish'
 publishing {	// 配置你的发布
    repositories {	// 配置发布的仓库,有多个可选择
    }
    publications {	// 配置发布的产出包,一个项目也有可能有多个产出,但大部分时候只有一个
    }
}

gradle 怎么 install 本地项目到本地maven仓库,供其他项目使用

首先,需要在gradle项目里面引入maven插件。命令很简单

apply plugin: 'maven' // 引入maven插件

引入之后,就会在侧边栏的命令里面看到install命令了

images

gradle项目一键转为maven项目

  1. 在build.gradle添加如下

  2. apply plugin: 'maven'
    

    执行安装

  3. gradle install
    

    执行完maven插件的安装后,在根目录下默认会生成三个子目录,如下:

    • libs:包含了名为${artifactId}-${version}.jar的jar文件
    • poms: 名为pom-default.xml的pom文件
    • tmp/jar: 包含了manifest信息
posted @ 2021-06-26 23:30  儒雅昌昌  阅读(374)  评论(0编辑  收藏  举报