Gradle 入门学习笔记

构建工具的作用

  • 构建管理
  • 自动化、测试、打包、发布

主流构建工具

ant、maven、gradle

Groovy

是基于 Java 虚拟机的一种敏捷的动态语言,是一种成熟的面向对象语言。即可以用于面向对象编程,又可以用于纯粹的脚本语言。同时又具有闭包和动态语言的其他特性。

特性:

  • 完全兼容 Java 语法
  • 分号可选
  • 类和方法默认是public
  • 编译器自动给属性添加 setter 和 getter 方法
  • 属性可直接用点号获取
  • 最后一个表达式的值会被作为返回值
  • == 号等同于 equals 、无空指针
  • 任何地方可以执行 assert (断言)

Groovy-高效特性

1.可选的类型定义(弱类型)

def version = 1     //类似js中的 var

2.assert 断言语句任何地方都可以执行

assert version == 1

3.括号是可选的

println(version)
println version     //等同于上

4.字符串的三种定义方式

def s1 = 'p'        //仅仅是字符串
def s2 = "gradle version is ${version}"        //可以插入变量
def s3 = '''
p
c
l'''        //可以换行
//println s1 + s2 + s3

5.集合API

list:

def buildTools = ['ant','maven']    //对应ArrayList
buildTools << 'gradle'              //追加
assert buildTools.getClass() == ArrayList
assert buildTools.size() == 3
println buildTools

map

def buildYears = ['ant':2000,'maven':1999]  //对应LinkedHashMap
buildYears.gradle = 1993        //追加
println buildYears.ant
println buildYears['gradle']
println buildYears.getClass().getName()

6.闭包
就是一个代码块,类似方法,可以有参数或无参数,可以被赋值给一个变量,也可以当做参数传递给一个方法,像普通方法一样调用,构建脚本中一般被当做方法参数来使用

//包含参数的闭包
def c1 = {
    //参数类型可以省略,箭头后面是方法体
    v ->
        println v
}

//不包含参数
def c2 = {
    println 'hello~'
}

//使用闭包作为参数的方法
def method1(Closure closure){
    closure('param')
}

def mothod2(Closure closure){
    closure()
}

method1(c1)
mothod2(c2)

构建脚本概要

构建块:

Gradle 构建中两个基本概念是 “项目”(project)和 “任务”(task),每个构建至少包含一个项目,项目中包含一个或者多个任务。在多项目构建中,一个项目可以依赖于其他项目;类似的,任务可以形成一个依赖关系图,来确保它们的执行顺序。

项目(project)

一个项目代表一个正在构建的组件(如 jar 文件),当构建启动后,Gradle 会基于 build.gradle 实例化一个org.gradle.api.Project 类,并且能够通过 project 变量使其隐式可用。

方法

  • apply:应用一个插件,是 project 中的一个方法
  • dependencies:申明项目依赖于哪些 jar 包或项目
  • repositories:去哪个仓库找要依赖的 jar 包
  • task:声明项目中有什么任务
  • ext:定义并引用,可以使用来统一管理不同 module 的版本号
  • gradle.properties:键值对形式申明一些属性并可引用
Groovy基础例子
apply plugin:'java'

构建脚本中默认是有一个project实例的,构建脚本里面所有的代码默认的作用域都是project,apply() 为 project 实例中的方法

version = 0.1

version 为 project 实例中的一个属性

repositories{
    mavenCentral()
}

repositories也是一个方法;{ mavenCentral() }闭包作为一个参数调用该方法

dependencies{
    compile 'commons-codec:commons-codec:1.6'
}

dependencies也是一个方法,{compile ‘commons-codec:commons-codec:1.6’ } 这也是一个闭包作为参数调用该方法

任务

对应org.gradle.api.Task,主要包括任务动作和任务依赖。任务动作定义了一个最小的工作单元(代码块)。任务还可以定义依赖于其他任务、动作序列和执行条件。

dependsOn: 申明任务依赖  
doFirst:   在任务列表的最前面添加一个动作条件  
doLast <<: 在任务列表的最后面添加一个动作
一个任务里可以执行多次 doFirst、doLast(动作列表里可包含多个动作)

setting.gradle

用来管理多项目构建

自定义任务

  1. 申明一个闭包,功能:根据传进来的路径创建文件

     def createDir = {
         path ->
             File file = new File(path);
             if (!file.exists()){
                 file.mkdirs()
             }
     }
    
  2. 使用 task 申明一个任务-创建java目录

     task makeJavaDir(){
         //定义存放目录的路径
         def paths = ['src/main/java','src/main/resources','src/test/java','src/test/resources']
         //给任务添加动作,在动作列表的前边插入一个动作
         //遍历这个目录结构,然后创建对应的目录
         doFirst{
             paths.forEach(createDir)
         }
     }
    
  3. 使用 task 申明一个任务-创建web目录

    java工程有的目录结构,web工程都有只是多了一个webapp目录,所以创建web目录任务依赖创建java目录任务,仅仅创建自己特有的目录就可以了

     task makeWebDir(){
         //申明该任务依赖 makeJavaDir 这个任务
         dependsOn 'makeJavaDir'
         //创建自己特有的目录
         def paths = ['src/main/webapp','src/test/webapp']
         //在这里跟doFirst作用一致,顺序相反而已
         doLast{
             paths.forEach(createDir)
         }
     }
    

完成后可在 Gralde-other 中查看,写完未出现的话刷新一下

构建生命周期

  1. 初始化
    初始化项目、有哪些项目需要参与到构建当中
  2. 配置
    生成 task 的依赖关系跟执行图
    dependsOn需要在这个阶段
  3. 执行
    执行动作代码

三个阶段后面都进阶一个 Hook 方法,可以进行处理一些自定义事件

依赖管理

几乎所有的基于JVM的软件项目都需要依赖外部类库来重用所有的功能。自动化的依赖管理可以明确依赖的版本,可以解决因依赖性传递带来的版本冲突

  • 依赖的传递性:

    B依赖,如果C依赖B,那么C依赖A

  • 依赖阶段配置:

    源代码阶段:compile、runtime
    测试代码阶段:testCompile、testRuntime

  • 依赖阶段关系:

    运行时阶段都是extends扩展与编译时阶段的、编译时依赖的jar包在运行时都会依赖、运行时依赖的在编译时不会依赖、源代码依赖的测试代码都会依赖、测试代码依赖的源代码不一定会依赖(具体搜索查看图解)
    使用编译时依赖:compile,则会在编译和运行时都寄来
    而使用运行时依赖:runtime则编译时不会依赖、只会在运行时依赖
    当有多个仓库的时候,会按仓库的顺序去查找jar包,如果第一个仓库中查找到jar包了就不会从后面的仓库去查找、如果第一个没找到就会从后面的去查找

  • 依赖冲突:

    当同一项目的多个依赖项中依赖了其他相同的依赖库,但是版本不一致

  • 解决冲突(Gradle默认处理方式是依赖最高版本的jar包,所以一般不需要我们自己处理)

  1. 使用 exclude 排除传递性依赖

  2. 使用相同的版本:强制制定一个版本
    以下配置可以修改Gradle默认处理策略,当有依赖冲突的时候回报错,help-dependices可以看到依赖详情;

     configurations.all{
         resolutionStrategy{
             failOnVersionConflict()
             //这里强制制定版本
             force'group:name:version'
         }
     }
    
  • 多项目构建

项目模块化

在企业项目中,包层次和类关系比较复杂,把代码拆分成模块通常是最佳实践,这需要你清晰的划分功能的边界,比如把业务逻辑和数据持久化拆分开来。项目符合高内聚低耦合时,模块化就变得很容易,这是一条非常好的软件开发实践.

实例

  1. 所有项目都应用java插件

    每一个moudle里都有一个 apply plugin:’java’,在根项目的build.gradle中配置
    注:(allprojects 应用在所有的Project中,包括root-project本身)

     allprojects {
         apply plugin:'java'
     }
    
  2. web子项目打包成 war 包

     在web子模块单独:apply plugin:'war'
    
  3. 所有项目添加统一依赖,如junit,这样就不用每个模块都写一遍

    注:(subprojects 用于配置所有的子Project(不包含根Project))

     subprojects {
         dependencies {
             testCompile 'junit:junit:4.12'
         }
     }
    
  4. 统一配置 group 和 version

    gradle.properties文件中配置:需要添加=号

     group = 'com.xxx.xxx'
     version = 1.0-SNAPSHOT
    

根项目的build.grdle可以配置每个模块统一的配置,子项目只需要配置自己个性化的配置,这样有利于统一管理和维护

如果想构建所有的项目,就在根项目下执行对应的任务,如果想执行单个项目的任务,就在单个项目下执行对应的任务

setting.gradle:用来管理根项目和子项目

发布到仓库(本地和远程)

maven-publish插件、配置、执行发布任务。

    原文作者:_Sisyphus
    原文地址: https://www.jianshu.com/p/40eb2aab0906
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞