1

时间:2017年05月16日星期二
说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com
教学示例源码:无
个人学习源码:https://github.com/zccodere/s...

第一章:课程介绍

1-1 项目自动化介绍

石器时代:自动化构建工具产生之前

依赖管理:将所有使用到的jar包放到lib目录下,不易管理,易出错
测试:能不写就不写,一个一个运行测试
打包:通过eclipse的export导出jar包或war包
上传:通过ftp工具进行上传到服务器解压运行

构建工具的作用

依赖管理:各种jar包及版本
测试、打包、发布:自动执行测试、打包、发布到指定的地方
机器能干的活,绝不自己动手

主流构建工具

Ant:编译、测试、打包
Maven:依赖管理、发布
Gradle:Groovy语言管理构建脚本

示意图

clipboard.png

Gradle是什么

一个开源的项目自动化构建工具,建立在Apache Ant和Apache Maven概念的基础上,并引入基于Groovy的特定领域语言(DSL),而不再使用XML形式管理构建脚本。

Gradle能做什么

进行依赖管理
自动化运行测试
打包
发布到指定地方

1-2 课程介绍

快速尝鲜

准备使用Gradle
第一个Gradle项目

基本原理

构建脚本介绍
依赖管理

深入实战

多项目构建
测试
发布

示意图

clipboard.png

第二章:准备使用Gradle

2-1 gradle安装

安装

确保已近安装JDK,java –version验证是否已经安装。
从Gradle官网下载Gradle,https://gradle.org
配置环境变量,GRADLE_HOME
添加到path,%GRADLE_HOME%\bin;
验证是否安装成功,gradle –v

2-2 Groovy理论介绍

Groovy是什么

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

与Java比较

Groovy完全兼容Java的语法
分号是可选的
类、方法默认是public的
编译器给属性自动添加getter/setter方法
属性可以直接用点号获取
最后一个表达式的值会被作为返回值
“==”等同于“equals()”,不会有NullPointerExceptions

高效的Groovy特性

assert语句
可选类型定义
可选的括号
字符串
集合API
闭包

2-3 Groovy与Java比较

Java语法编写标准JavaBean

代码演示:

public class ProjectVersion{
    private int major;
    private int minor;

    public ProjectVersion(int major,int minor){
        this.major = major;
        this.minor = minor;
    }

    public int getMajor(){
        return major;
    }

    public void setMajor(int major){
        this.major = major;
    }

    public int getMinor(){
        return minor;
    }

    public void setMinor(int minor){
        this.minor = minor;
    }
}

Groovy语言编写JavaBean

class ProjectVersion{
    private int major
    private int minor
    ProjectVersion(int major,int minor){
        this.major = major
        this.minor = minor
    }
}

2-4 Groovy高效特性

Groovy高效特性

可选的类型定义
assert断言
括号是可选的
字符串
集合API

代码演示:

// 高效特性
// 1 可选的类型定义
def version = 1

// 2 assert
//assert version == 2

// 3 括号是可选的
println version

// 4 字符串
def s1 = 'imooc'
def s2 = "gradle version is ${version}"
def s3 = '''my
name is
imooc'''

//println s1
//println s2
//println s3

// 5 集合API
// list
def buildTools = ['ant','maven']
buildTools << 'gradle'
assert buildTools.getClass() == ArrayList
assert buildTools.size() == 3
// map
def buildYear = ['ant':2000,'maven':2004]
buildYear.gradle = 2009

//println buildYear.ant
//println buildYear['gradle']
//println buildYear.getClass()

// 6 闭包
def c1 = {
    v ->
        print v
}
def c2 = {
    print 'hello'
}
def method1(Closure closure){
    closure('param')
}
def method2(Closure closure){
    closure()
}
method1(c1)
method2(c2)

2-5 Groovy重点

代码演示:

// 构建脚本中默认都是有Project实例的
//Project实例的apply方法
apply plugin:'java'
//Project实例的version属性
version = '0.1'
// 闭包作为参数调用repositories方法
repositories {
    mavenCentral()
}
// 闭包作为参数调用dependencies方法
dependencies {
    compile 'commons-codes:commons-codes:1.6'
}

第三章:第一个Gradle项目

3-1 第一个Gradle项目介绍

示例介绍

ToDo应用程序,只实现添加代办事项
Java应用程序版
Web版

3-2 应用程序版

目录结构

clipboard.png

3-2 Web版

代码演示:

group 'com.myimooc'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

configurations.all {
    resolutionStrategy {
        failOnVersionConflict()
        // 强制指定一个版本
        force 'org.slf4j:slf4j-api:1.7.22'
    }
}

repositories {
//    maven{
//        url ''
//    }
    mavenLocal()
    mavenCentral()
}

dependencies {
    // https://mvnrepository.com/artifact/org.hibernate/hibernate-core
    compile (group: 'org.hibernate', name: 'hibernate-core', version: '3.6.3.Final'){
        // 排除传递依赖
        exclude group:'org.slf4j',module:'slf4j-api'
    }
    // https://mvnrepository.com/artifact/ch.qos.logback/logback-classic
    compile 'ch.qos.logback:logback-classic:1.2.3'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}
// 声明 闭包:创建目录,需传入参数为字符串目录路径
def createDir = {
    // 参数
    path ->
        // 功能
        println path
        File dir = new File(path);
        if(!dir.exists()){
            dir.mkdirs();
        }
}

// 任务:自动创建Java工程目录结构
task makeJavaDir(){
    // 定义数组存放目录路径
    def paths = ['src/main/java', 'src/main/resources', 'src/test/java', 'src/test/resources'];
    // 添加动作:doFirst:在动作列表的前面插入一个动作
    doFirst{
        for(String path : paths){
            // 调用 闭包
            createDir(path)
        }
    }
}
// 任务:自动创建Web工程目录结构
task makeWebDir(){
    // 声明当前任务依赖 makeJavaDir 任务
    dependsOn 'makeJavaDir'
    def paths = ['src/main/webapp', 'src/test/webapp']
    // 添加动作:doLast:在动作列表的后面插入一个动作
    doLast{
        for(String path : paths){
            // 调用 闭包
            createDir(path)
        }
    }
}

第四章:高级应用

4-1 构建脚本介绍

构建块

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

clipboard.png

项目(Project)

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

项目的属性和方法

group、name、version
apply、dependencies、repositories、task
属性的其他配置方式:ext、gradle.properties

任务(task)

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

任务的方法

dependsOn
doFirst、doLast<<

4-2 自定义任务

代码演示:

// 声明 闭包:创建目录,需传入参数为字符串目录路径
def createDir = {
    // 参数
    path ->
        // 功能
        println path
        File dir = new File(path);
        if(!dir.exists()){
            dir.mkdirs();
        }
}

// 任务:自动创建Java工程目录结构
task makeJavaDir(){
    // 定义数组存放目录路径
    def paths = ['src/main/java', 'src/main/resources', 'src/test/java', 'src/test/resources'];
    // 添加动作:doFirst:在动作列表的前面插入一个动作
    doFirst{
        for(String path : paths){
            // 调用 闭包
            createDir(path)
        }
    }
}
// 任务:自动创建Web工程目录结构
task makeWebDir(){
    // 声明当前任务依赖 makeJavaDir 任务
    dependsOn 'makeJavaDir'
    def paths = ['src/main/webapp', 'src/test/webapp']
    // 添加动作:doLast:在动作列表的后面插入一个动作
    doLast{
        for(String path : paths){
            // 调用 闭包
            createDir(path)
        }
    }
}

4-3 构建生命周期

构建生命周期

初始化:初始化需要参与构建的项目
配置:根据配置代码生成task的依赖顺序和执行顺序
执行:执行动作代码

示意图:

clipboard.png

构建周期构造方法

clipboard.png

4-4 依赖管理

概述

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

工件坐标

group:工件组
name:工件名称
version:版本
通过这三个属性来唯一确定一个jar包

常用仓库

mavenCentral:公共仓库
jcenter:公共仓库
mavenLocal:本地仓库
自定义maven仓库:maven私服,公司内部仓库
文件仓库:不建议使用

依赖的传递性

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

自动化依赖管理

clipboard.png

依赖管理阶段

源代码:compile:编译阶段;runtime:运行阶段。
测试代码:testCompile:编译阶段;testRuntime:运行阶段。

依赖阶段关系

clipboard.png

4-5 解决版本冲突

版本冲突例子

clipboard.png

解决冲突

查看依赖报告
排除传递性依赖
强制指定一个版本

clipboard.png

clipboard.png

clipboard.png

4-6 多项目构建介绍

项目模块化

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

TODO模块依赖关系

clipboard.png

配置要求

所有项目应用Java插件
web子项目打包成war
所有项目添加logback日志功能
统一配置公共属性

项目范围

clipboard.png

4-7 多项目构建实战

详见源代码。

4-8 自动化测试

自动化测试

一些开源的测试框架比如JUnit,TestNG能够帮助你编写复用的结构化的测试,为了运行这些测试,你要先编译它们,就想编译源代码一样。测试代码的作用仅仅用于测试的情况,不应该被发布到生产环境中,需要把源代码和测试代码分开来。

项目布局

clipboard.png

测试配置

clipboard.png

测试任务

clipboard.png

测试发现

任何继承自junit.framework.TestCase或groovy.util.GroovyTestCase的类
任何被@RunWith注解的类
任何至少包含一个@Test注解的类

4-9 发布

发布到本地和远程仓库

clipboard.png

发布过程

使用maven-publish插件
配置发布任务,仓库地址
执行发布任务,发布完成

第五章:课程总结

5-1 课程总结

示意图

clipboard.png


妙手空空
1.3k 声望370 粉丝

博观而约取,厚积而薄发