Gradle 是一种开源自动化构建工具,支持多语言环境,受 Ant、Maven 思想的影响,集二者之大成,相比 Ant 的不规范,Maven 的配置复杂、生命周期限制严重,Gradle 既规范也更灵活,可以使用DSL (领域特定语言,如Groovy 或 Kotlin)编写构建脚本,脚本更短小精悍
它的特性有:
- 高度定制化:模块化可扩展,更灵活
- 构建迅速:支持并行构建,自动复用之前任务构建的结果以提高效率
- 功能强大:支持多语言环境,包含 Java、Android、C++、Groovy、Javascript 等项目的构建
Ant、Maven 有的 Gradle也有,Gradle有的它们不一定有;
Ant、Maven能干的,Gradle 都能干,而且干得更好
Gradle 二进制包安装流程:
- 确保 JDK 正确安装
- 下载最新版 Gradle https://gradle.org/releases/
- 解压到指定目录
- 设置 path
- 测试
以 Linux 举例:
build.gradle
的作用是静默输出,使输出更加清晰
这里发生了什么? 这个构建脚本定义了一个独立的 task, 叫做 hello, 并且加入了一个 action,当你运行 gradle hello, Gradle 执行叫做 hello 的 task, 也就是执行了你所提供的 action. 这个 action 是一个包含了一些 Groovy 代码的闭包(Closure)
扩展阅读:
task块内可以定义前置、后置执行的方法(闭包)、,按字面意思来理解就可以,但要注意,定义多个doLast或doFirst无法保证执行顺序
和 是 Gradle 中最重要的两个概念。
任何一个 Gradle 构建都是由一个project或多个 projects 组成。每个 project 或许是一个 jar 包或者一个 web 应用,它也可以是一个由许多其他项目中产生的 jar 构成的 zip 压缩包。
每个 project 都由多个 tasks 组成。每个 task 都代表了构建执行过程中的一个原子性操作。如编译,打包,生成 javadoc,发布到某个仓库等操作。
简单来说,project 相当于一个构建工程的一个模块,而 task 是其中一个模块的一个操作
在 build.gradle (可以称为build script,构建配置脚本) 中可以调用 Groovy 的类库(也包含 Java 类库),下面是示例:
build.gradle
执行命令
此示例中简单地将 转成了 ,其中使用了 String 的 方法
Groovy 兼容 Java 语法,我们可以通过在 task 中调用 Groovy 或 Java 的方法来完成想做的操作
在 Maven 中,可以明确定义项目版本,构建时会将这个版本包含在 war 或 jar 等制品的文件名称中,推送到 Maven 私服中也需要设置 信息,那么 Gradle 中如何定义呢?
Gradle 中,对应 Maven 的三个参数,将 变成了 ,那么只需额外定义 与
在 中设置
Gradle 配置中还有一个特殊的配置文件,,我们可以在里边配置变量供 读取
使用 Maven 时我们可以通过以下命令来创建一个简单的 Java 项目
Maven 有的 Gradle 自然也不会落下,我们可以使用 来初始化一个 Java 项目
生成代码的结构如下:
当 task 执行的时候,优先调用 task 来生成 、 以及新项目所需的代码结构
带大家读文档 https://guides.gradle.org/building-java-applications/
- 作用:将当前项目打成war包
- 使用:
- 中添加 或在 块中添加
- ,生成war到当前项目目录根build/libs下
带大家读文档并实践 https://guides.gradle.org/building-spring-boot-2-projects-with-gradle/
由于国内网络问题,需要配置国内源和插件源,这里把本人测试时的主要部分放出来
项目结构就是官方文档中的那样
包下的 APP.java :
build.gradle :
settings.gradle :
- 步骤:
- 添加 插件
- 执行 或 (build会执行很多操作,booWar编译后只打war包)
- 打包出可直接执行启动的war(内嵌tomcat)
- 屏蔽tomcat依赖,继承 SpringBootServletInitializer,重写configure方法
build.gradle
App.java
执行的 task 很多,这里放下输出
- bootWar: 编译并打成war包(需要依赖war插件才会有这个task),内部先调用classes,再调用自身,两个 task
- bootJar: 编译并打成jar包,内部先调用classes,再调用自身,两个 task
- compile:从仓库里下载并编译,支持依赖传递
- api:新语法,等同compile
- implementation:新语法,与api相比不支持传递依赖,减少循环编译优化效率
compile/api/implementation导入的依赖都是编译期与运行期都会提供的(打进制品中)
扩展阅读:
implementation作用域
implementation的“访问隔离”只作用在编译期。
什么意思呢?如果lib C 依赖了lib A 2.0版本,lib B implementation依赖了lib A 1.0版本:
那么编译期,libC 可访问2.0版本的libA,libB可访问1.0版本的libA。
但最终打到war中的是2.0版本(通过依赖树可看到)。
在运行期,lib B 和lib C都可访问lib A的2.0版本(只能用war中的lib)
implementation的特点有哪些?
对于使用了该命令编译的依赖,对该项目有依赖的项目将无法访问到使用该命令编译的依赖中的任何程序,也就是将该依赖隐藏在内部,而不对外部公开
使用implementation有什么好处?
如果项目中有很多级联的工程依赖,比如上图中lib A B C的依赖是工程依赖。如果使用的依赖方式是compile/api,那么当lib A接口修改后重新编译时,会重新编译libA B C(即使lib C中并没有用到修改的libA的接口)。如果使用implementation依赖,因为“编译期隔离”的原因,不直接相关的lib就不会进行重新编译。
如果项目中都是aar依赖,编译减少时长这个优点就没有了(因为aar已经是编译好的字节码了)。那么还有什么用呢?还是以上图为例。之前我们都是compile依赖,如果lib A已经依赖了lib B,那么在libC的build.gradle中就不用写lib A的依赖了。但这样会有问题:
- providedCompile:编译期参与编译,运行期不提供(但生成的war包中,会将这些依赖打入WEB-INF/lib-provided中)
- providedRuntime:不参与编译但运行期需要,比如 mysql 驱动包,如果在代码里用到了此依赖则编译失败
- testCompile:测试期编译,非测试期不编译
- testImplementation:与implementation相同,仅是测试周期的
- exclude:排除指定 group module的模块
- 引入依赖时屏蔽
- 全局屏蔽
或
- dependencyManagement:统一多模块依赖版本
- 可以在里边定义 dependencies 块,指定依赖版本
- 可以引入BOM,类似引入Maven的parent
参详官方文档:
- https://gradle.org/guides/
- https://docs.gradle.org/current/userguide/userguide.html
- 官文文档 见上一小节【更多】,本文参考文档 6.4.1
- Spring Boot Gradle Plugin Reference Guide
- SpringBoot及SpringCloud版本管理(Gradle版本)
- Gradle深入与实战(转)
- Android Gradle Task详解
- Gradle与Maven的区别
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/5939.html