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()的配置
- mavenLocal()表示使用本地maven仓库
- mavenCentral()使用maven中心仓库
- 使用阿里云(maven {url 'http://maven.aliyun.com/nexus/content/groups/public/'})#这个相当于使用自定义maven仓库地址的配置,可以是私服。
- 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默认本地依赖存储位置
- 因为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')
-
引入远程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:+'
settings.gradle
-
build.gradle - 文件包含项目构建所使用的脚本。
-
settings.gradle - 文件将包含必要的一些设置,例如,任务或项目之间的依懒关系等
-
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配置
- Gradle官方非常贴心的内置了插件,可以一键将Maven POM转换为Gradle配置。只需要在项目目录内执行,(pom所在的文件夹路径下执行,就会自动生成build.gradle)
- 然后,按照提示,将该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之多项目构建
- Gradle对构建模块化项目提供了强大的支持,在Gradle中每一个模块都是一个项目,称之为Gradle多项目构建技术,多项目构建实现了项目模块化,降低代码耦合度,增加内聚性。
- 组装多项目构建: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文件介绍
一个项目中只放置一个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 插件(Plugins)
- 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 {}”块似乎是一个新引入的还不足够稳定的特性。题主想要知道更多的话直接看看文档就行了。
实现自定义的插件
- 在我们构建项目的 build.gradle 脚本中直接编写,这种方式的好处是插件会自动被编译加载到我们的 classpath 中,我们不需要额外做任何的事情,但是它有很明显的局限性,就是除了在包括它的脚本外别的地方无法复用。
- 在我们构建项目的rootProjectDir/buildSrc/src/main/groovy 目录下编写,Gradle 会自动编译到当前项目的classpath中,该项目下所有编译脚本都可以使用该插件,但是除了当前项目之外的都无法复用。
- 以单独的工程方式编写,这个工程最终编译发布为一个 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的区别
- implementation不可以传递依赖,但是compile可以传递依赖。
- api和compile关键字作用效果是一样的,使用时可以互相替换。实际上,api关键字是用来替代compile关键字的,因为compile关键字将来会被弃用。在高版本的gradle,使用compile关键字会报错并提示使用api关键字代替
- 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'
}
依赖本地文件:
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(),如下:
image.png
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
mavenLocal()
mavenCentral()
}
以上表示,先从本地仓库寻找 jar 包,若找不到,再从中央仓库下载.
使用gradle命令行创建一个Java项目
-
新建一个文件夹,即为项目文件夹,然后创建一个文件。 build.gradle
-
build.gradle是Gradle的配置文件
-
//(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() } }
-
执行命令
-
gradle create-dirs
然后就生成了项目。
gradle其实就是在maven的基础上简化了pom配置,使用简洁的风格,不用写很长的xml文件。
gradle使用task的方式执行任务,一个操作由多个task共同完成,清晰的展现在日志中。
gradle启动脚本
gradle通过调用一个名字叫gradlew
的脚本然后加载了gradle-wrapper.jar
最终才开始执行gradle命令。
使用Gradle Wrapper
对于所有的Gradle项目来说,笔者都推荐使用Gradle Wrapper,甚至应该将其当做创建代码库之后的第一件事来做。使用Gradle Wrapper有以下好处:
- 不用安装gradle也能运行gradle
- 所有人使用相同的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'
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依赖下载存放路径
2、在IDEA下手动配置依赖下载路径
对于IDEA来说没有用(当然上面的环境变量还是要添加的),在IDEA中使用gradle需要修改下面的路径
浏览量: 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)
}
}
}
gradle install项目到maven本地和远程仓库
引用插件
apply plugin: 'maven-publish'
publishing { // 配置你的发布
repositories { // 配置发布的仓库,有多个可选择
}
publications { // 配置发布的产出包,一个项目也有可能有多个产出,但大部分时候只有一个
}
}
gradle 怎么 install 本地项目到本地maven仓库,供其他项目使用
首先,需要在gradle项目里面引入maven插件。命令很简单
apply plugin: 'maven' // 引入maven插件
引入之后,就会在侧边栏的命令里面看到install命令了
gradle项目一键转为maven项目
-
在build.gradle添加如下
-
apply plugin: 'maven'
执行安装
-
gradle install
执行完maven插件的安装后,在根目录下默认会生成三个子目录,如下:
- libs:包含了名为${artifactId}-${version}.jar的jar文件
- poms: 名为pom-default.xml的pom文件
- tmp/jar: 包含了manifest信息