`
frank-liu
  • 浏览: 1665347 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

gradle学习总结

 
阅读更多

简介

  Java的自动化构建工具比较多,从最开始的ant,到maven以及现在的gradle。他们的灵活性和功能越来越强大。相对前面的工具来说,gradle使用专门的编程groovy来描述项目构建过程中的一些任务。由于有编程语言的灵活性,它的表达能力更加强,结合一些强大的插件支持,我们可以使用少量的代码和配置来达到项目构建的目的。这里针对一些常见的问题做一个总结。

 

安装

    gradle的安装过程相对来说还是比较简单的,一种最简单的方法就是到它的官网下载:https://gradle.org/gradle-download/。将gradle下载到本地之后,解压到某个目录并设置好gradle的bin目录到PATH环境变量就可以了。

  为了验证gradle的安装情况,可以打开命令行输入如下命令:

 

gradle --version

  如果一切安装配置正确的将显示如下的结果:

 

  当然,安装gradle需要先安装java。Java的安装过程在这里就不详述了。 

 

常用命令

  在前面验证gradle安装过程中我们已经尝试过gradle --version的命令。还有一些比较常见的命令。

 

帮助命令

  当我们输入命令:

gradle --help

将显示如下的内容:

 

  在不知道gradle有哪些命令选项的情况下,我们会通过这个命令来查看。

 

查看task列表

  gradle在某种程度上和ant也比较像,它里面也像ant一样定义了很多task。像ant里面定义的task是xml形式的,它定义不同任务的顺序,依赖关系等。而gradle里的任务的概念和ant里的差不多,只是它更加灵活。这些task可以是一些插件带的也可以是一些自定义的。

  查看任务列表的命令如下:

gradle tasks

  一般该命令会显示工程里面定义的所有任务,一个典型的示例如下:

 

 

项目初始化

  不管是ant, maven还是gradle,他们都有一个用来描述项目构建逻辑的文件。gradle里常用的是使用build.gradle文件来描述它们。如果用命令行来初始化一个gradle工程的话,可以使用命令:

gradle init

  当我们在命令行里输入上述的命令的话会在当前目录生成一个如下结构的一系列文件:

 

 

   这样,一个空的gradle工程就生成了。如果我们看这个目录结构的话会发现这里还多了两个可执行的文件,gradlew和gradlew.bat。它们分别对应于linux和windows系统的可执行文件。因为在不同的目标环境中不一定在机器中安装了gradle,那么就可以通过工程里自带的这个可执行文件来执行gradle相关的命令。这样节省了安装工具的时间。当然,如果我们要在原有的工程中生成这些可执行文件可以通过命令

gradle wrapper

 来生成。

 

自定义任务

project方法

  gradle的build脚本从实质上来说就是一个groovy脚本,它里面所有的元素都是基于project和task这两个类。而project和task就是groovy里两个定义好的类,它预先包含了一系列的属性和方法。一些常用的属性和方法有apply, repositories,dependencies。比如说,我们需要在一个工程里使用java插件,并且定义依赖库所在的repository以及所依赖的详细的类库。我们可以使用如下脚本:

 

project.apply plugin: 'java'

project.repositories {
	mavenCentral()
}

project.dependencies {
	testCompile 'junit:junit:4.11'
}

  这里指定了所使用的java plugin,依赖的详细类库信息。实际上,因为project是脚本里默认定义的类,在实际的脚本里可以省略这一部分:

apply plugin: 'java'

repositories {
	mavenCentral()
}

dependencies {
	testCompile 'junit:junit:4.11'
}

  

project属性

    project类除了上述的方法,还有一些有用的属性用于具体项目的定制。有的属性是只读的,比如name, path, parent等。也有一些属性是可写的,比如说project.description, project.version。这些属性可以被一些任务所使用到,比如用来设置编译打包项目版本的任务。

  比如说我们定义一个如下的gradle脚本:

description = "a sample project"
version = "1.0"

task printProperties {
    doLast {
        println project.version
        println project.description
    }
}

 运行命令gradle printProperties则会输出 

1.0
a sample project

 

extra properties

  除了前面project定义的一些属性,还有一些用户自定义的属性也可以放在脚本里。一种简单的方式就是将一些自定义的属性字段放到一个ext的命名空间里。比如说我们可以将前面的示例修改成如下:

description = "a sample project"
version = "1.0"

ext {
    springVersion = "4.3.2.RELEASE"
    emailNotification = "noreply@master.org"
}

task printProperties {
    doLast {
        println project.version
        println project.description
        println springVersion
        println emailNotification
    }
}

  这个时候再执行命令gradle printProperties则输出如下的结果:

 

:printProperties
1.0
a sample project
4.3.2.RELEASE
noreply@master.org

 

依赖配置和声明

  在前面的讨论里我们已经看到了在gradle脚本里怎么声明依赖。我们就是需要在dependencies命名空间下添加所有需要依赖的类库信息就可以了。以上面的示例代码为例:

dependencies {
	testCompile 'junit:junit:4.11'
}

   这里声明了对junit库的依赖,在依赖部分里testCompile定义了依赖的范围为testCompile,也就是在测试编译的时候依赖的内容。后面由冒号分开的三个部分分别表示依赖库的group id, artifact id和版本号。对于依赖的库可以通过search.maven.org 来查找。

  除此之外,还有一个值得注意的问题就是依赖范围的定义。在gradle里,对依赖的定义有6种,他们分别是compile, runtime, testCompile, testRuntime, providedCompile和providedRuntime。它们有不同的适用范围。

  • compile: 这是java plugin所引入的一个配置项,它表示程序代码里需要引用这个库才能进行编译工作。像我们在编程中通常引入的spring framework, hibernate等。因为这些库在程序里有直接或者间接的引用。所以被定义为compile类型。大多数我们引用的库就是这个范围的。
  • runtime:  这也是java plugin引入的一个配置项。它默认的包含compile依赖。它主要表示这些依赖的库只是在运行的时候需要用到,但是在编译的时候并不需要。典型的比如jdbc的驱动程序。我们在应用程序里只是基于标准的jdbc api来开发,但是在程序具体运行的时候需要指定针对某个数据库的具体驱动程序。比如'mysql:mysql-connector:5.1.37'。
  • testCompile: 这也是java plugin引入的配置项。它默认会包含有compile的配置范围。它主要表示在测试代码里所涵盖的引用依赖。在程序代码里并不依赖它。一些常用的库比如JUnit, TestNG, Mockito等都适用于这个范围。
  • testRuntime: 这也是java plugin引入的配置。它默认包含有testCompile, runtime的依赖范围。主要表示测试的代码在运行的时候需要的依赖。这些依赖一般不直接用于测试代码的编译中。
  • providedCompile: 这是war plugin引入的配置。对于war plugin所涵盖的范围,它主要是引用在一些java web的程序中。所以有一些依赖的api,比如servlet api, 一些应用程序服务器提供的api在编译的时候不需要打包到war包里头,但是它们又需要引用它们,因为它们已经在所运行的服务器里包含了。
  • providedRuntime: 这也是war plugin引入的配置。它表示一些在编译的时候不需要提供的依赖库,但是在运行的时候需要。它们一般也是已经包含到应用服务器中了。

tasks

    在之前的脚本里我们已经见过一些task定义的示例了。比如说有如下的:

 

task hello {
    doLast {
        println 'Hello world!'
    }
}
  要运行这些task,则需要在gradle命令后面跟上这个task的名字。像这个示例里需要运行gradle hello就可以了。 

 

 

task配置

  task定义好之后,它实际上就是一个groovy的方法。那么在这个方法里,也就是定义的gradle脚本里,我们可以配置它的具体参数。比如有一个如下的task:

 

 

task('copy', type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}
  这是一个实现文件拷贝的task。我们可以在task的详细定义里添加更多的内容来定制它们。比如说,我们可以将上述的内容修改成:

 

 

task myCopy(type: Copy)
myCopy {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}
   这样可以在详细的任务执行里设定详细的参数值。

 

task依赖

  这一点和ant里面定义的task很相似,当一个task它的执行需要依赖于另外一个task的时候,我们需要定义它们的依赖关系以防止逻辑错误。在gradle里面定义这个关系很简单,可以在task声明里定义。比如如下的示例:

 

task compile {
	println 'compile the source'
}

task dist(dependsOn: compile) {
	println 'prepare a jar dist'
}

  对于多个task的依赖来说,我们可以将依赖描述部分放在task声明里或者另外一个单独的地方。比如有如下的脚本:

task compile {
	doLast {
		println 'compile the source'
	}
}

task testCode {
	doLast {
		println 'test code'
	}
}

task dist(dependsOn: [compile, testCode]) {
	doLast {
		println 'prepare a jar dist'
	}
}

   这时候如果我们运行task dist,会先执行它依赖的compile和testCode任务。

 

 

常见的项目构建插件

  gradle作为构建工具来说,更多被拿来相比较的工具就是maven了。和maven类似,为了支持常用项目的构建,它定义了很多常用的插件,这样对一些常用的项目,比如java工程,java web工程等它都有很好的支持。这些事先定义好的插件包含了一系列的任务,这些任务在很多工程里有一定程度的通用,可以极大的提高工作效率。

 

java plugin

  一个常用的插件就是java,要使用这个插件,只需要在构建文件build.gradle里添加如下的代码即可:

apply plugin: 'java' 

  如果此时我们运行命令gradle tasks,会发现输出结果里多了很多task。

 

  这些task就是java plugin里面自带的,常用一些比如编译代码的任务compileJava, 打包程序的任务assemble, build以及测试程序的任务testClasses。 更详细的任务列表以及关系可以通过gradle tasks --all来查看。由于不同的任务有一定的依赖关系,所以我们会看到像build任务是依赖于assemble, check等任务的。这种现象在gradle里很常见。

    假设我们创建一个如下的目录结构:

 

  这里建立了一个普通的java工程目录结构,其中GreetingService.java和Main.java的详细实现如下:

package com.packtpub.ge.hello;

public class GreetingService {
  public String greet(String user) {
    return "Hello " + user;
  }
}

 

package com.packtpub.ge.hello;

public class Main {
  public static void main(String[] args) {
    GreetingService service = new GreetingService();
    System.out.println(service.greet(args[0]));
  }
}

  这个时候,如果我们需要编译程序,只需要运行命令

gradle compileJava

  运行结束后的程序目录结构如下:

 

  从目录结构中可以发现,编译完之后的代码会被放到一个build的目录下面。而如果需要将编译后的代码打包,则可以执行命令

gradle build

  这个时候的程序目录结构如下:

 

  我们可以看到对应的jar包也生成在build目录下了。这个包名和我们创建这个工程的目录名是一样的。如果想要设置生成的jar包名,只需要在build.gradle里添加指定这个包名的内容即可:

archivesBaseName = "my-app"

 如果我们再运行前面的命令会发现新生成的包名变了。而实现编译打包等功能来处理这个工程的build脚本非常简单,只有两行:

apply plugin: 'java'

archivesBaseName = "my-app"

  在java plugin里还有一个比较重要的task,就是将编译打包后的结果上传到某个地方,比如本地的文件或者repository服务器上。比如说我们像将本地的工程包上传到某个maven服务器,则可以使用如下的配置:

uploadArchives {
	repositories {
		maven {	
			credentials {
				username "user1"
				password "user1"
			}
			url "http://company.private.repo"
		}
	}
}

  在后续项目的开发中,如果需要引用到这个库就和引用公开的第三方库一样方便了。当然,如果像将工程包放到本地的一个目录上,也可以这样设置:

uploadArchives {
	repositories {
		flatDir {dirs "./tempRepo"}
	}
}

 

application plugin

  在前面java pllugin里,我们发现它定义了很多tasks用来提高项目的编译测试等任务,在某些情况下,如果我们希望直接通过gradle命令来将项目打包运行和发布的话。还有一个经常要用到的插件是application。同样,我们只需要在原来的脚本里添加一行代码将这个插件包含进来就可以了。以前面的示例为基础,假设我们想要运行这个程序,那么可以将build.gradle修改如下:

apply plugin: 'java'
apply plugin: 'application'

mainClassName = "com.packtpub.ge.hello.Main"

run.args = ["Reader"]


repositories {
  mavenCentral()
}

dependencies {
  testCompile 'junit:junit:4.12'
}

  在上述的脚本里,我们不仅仅引入了application plugin,而且还设定了程序运行时的主入口启动类和程序的启动输入参数。所以如果运行命令:

 

gradle run

我们将看到如下的结果:

 

:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello Reader

  当然,除了上述的启动运行程序的命令,application plugin还提供了一些程序打包的任务支持。如果我们运行命令:

 

gradle distZip

  在项目中会增加一个.zip的打包好的文件。最终的目录结构如下:

 

    application plugin带来的更多任务可以通过gradle tasks来查看。 

 

war plugin

    war plugin主要是应用于java web工程里,它和java plugin之间还是一个继承的关系。也就是说,如果我们的应用里引入了war plugin,就没必要再引用java plugin了。

  一个简单的java web工程对应的配置如下:

apply plugin: 'war'

repositories {
  mavenCentral()
}

dependencies {
  providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

  在脚本里面,我们只需要指定插件和依赖的库,然后感觉所有需要的东西就已经具备了。 假设我们工程目录结构如下:

  它的详细实现代码见后面附件里的内容。如果我们需要将程序打包的话,只需要执行命令:

gradle war

  就会发现在build/lib的目录下有一个打包好的war包了。 

  关于java web工程来说,还有一个重要的问题就是要运行这些打包的结果。以往我们都是采用手动的过程将打包好的内容拷贝到一个应用服务器的指定目录里,比如tomcat, jetty等。实际上gradle里也有对应的插件来支持,这样就使得我们运行web工程的效率更加高。一个典型的插件就是gretty。

  因为gretty不是gradle原生自带的插件,它是一个扩展的插件,我们需要指定它的版本等信息。

 

plugins {
  id "org.akhikhl.gretty" version "1.4.0"
  id 'war'
}

gretty {
  servletContainer = 'tomcat8'
  port = 8080
}

repositories {
  mavenCentral()
}

dependencies {
  providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

  这里,因为gretty是指定工程运行的插件,它需要提供我们运行的时候是使用的哪个服务器以及运行时的端口。所以需要指定servletContainer和port。像这里指定的是使用tomcat8服务器,启动的端口是8080。如果我们想使用别的服务器,比如jetty9,可以将上述代码里gretty的部分修改成如下的内容:

gretty {
  servletContainer = 'jetty9'
  port = 9080
}

  运行工程应用的命令则比较简单,使用命令:

gradle appRun

程序启动后会显示如下内容:

 

   打开浏览器就能访问我们创建的应用了。

 

多工程构建

  在我们实际的工程应用中,经常会创建多个工程,而且这些工程之间有一定的依赖关系。那么我们经常需要将这些多个工程组织起来。我们可以通过一个对应的配置文件来实现。

  比如说我们有一个如下的项目,它由多个工程组成:

  在图中显示至少包含有core, web两个工程。那么,我们可以将这个build里面所有需要引用到的工程定义在settings.gradle文件里。比如说:

include 'core',
  'core:models', 'core:repository', 'core:services',
  'client', 'client:client-api',
  'client:cli-client', 'client:desktop-client',
  'web', 'web:webapp', 'web:webservices'

  这个时候,如果我们运行命令:

gradle projects

    我们将看到如下的结果:

 

   这里比较有意思,虽然在项目的结构里我们只看到有两个子工程,但是通过定义好的settings.gradle文件,程序逻辑里包含的工程还是以这个文件为基础的。

  这里还有一个比较有意思的地方在前面的依赖定义部分没有提到。就是有时候我们定义的多个工程中间它们某些相互有依赖的关系。那么我们需要在文件里面也给定义出来。在这里它们的使用方式和前面的依赖管理很相似。在settings.gradle文件里定义好总体的包含关系之后。只需要在具体的某个工程里引入就可以了。比如说我们有工程web-app,它依赖于另外一个工程services。那么我们只需要在web-app里面的build.gradle里添加如下内容:

 

dependencies {
  compile project(':services')
}

  这样,就解决了项目之间的依赖关系。这和引用一个类库的方式几乎一样。

 

IDE集成插件

      我们使用gradle开发如果和一些集成开发工具结合起来更能够提升项目开发的效率。所以gradle里也提供了对常用开发工具的支持,比如eclipse, IDEA等。如果需要引入它们的话,只需要在工程里引入对应的plugin就可以了。比如说,我们想要让工程支持eclipse和IDEA的导入。我们可以在build.gradle里加入如下部分:

apply plugin: 'eclipse'
apply plugin: 'idea'

  如果我们希望在对应的IDE里导入它们,只需要执行命令:

gradle eclipse

  或者:

gradle idea

  就可以了。这样可以充分利用IDE带来的便利。 

 

总结

    gradle是一个比较新的项目编译构建工具,它因为是基于groovy来构造项目构建的逻辑,所以有充分的表达能力和灵活性。这里针对常用项目开发里使用到的一些功能做一个总结。包括有它的安装配置,常用的插件和一些自定义任务的构建。实际上gradle还有很多很灵活的应用值得我们去深入学习思考,而且,它本身使用的编程语言groovy也值得进一步的学习。

 

参考材料

https://gradle.org/

https://www.amazon.com/Gradle-Essentials-Community-Experience-Distilled/dp/1783982365/ref=sr_1_1?s=books&ie=UTF8&qid=1482032176&sr=1-1&keywords=gradle+essentials 

  • 大小: 27.8 KB
  • 大小: 63.8 KB
  • 大小: 85.6 KB
  • 大小: 13.7 KB
  • 大小: 36.5 KB
  • 大小: 11.4 KB
  • 大小: 26.3 KB
  • 大小: 31 KB
  • 大小: 48.6 KB
  • 大小: 18.5 KB
  • 大小: 45.1 KB
  • 大小: 8.2 KB
  • 大小: 47.8 KB
分享到:
评论

相关推荐

    你该知道的Gradle配置知识总结

    本文主要介绍了关于Gradle配置的相关知识,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 参考链接:https://developer.android.com/studio/build/index.html 本片文章的内容全部参考自上面的...

    使用springboot+gradle框架开发百度AI人脸识别接口。外加小程序的两个接口。主要是框架搭建。.zip

    总结来说,【小程序名称】凭借其小巧便携、快捷高效的特性,不仅节省了用户的手机存储空间,更为用户提供了无缝衔接的便利服务,是现代生活中不可或缺的一部分,真正实现了“触手可及”的智能生活新体验。...

    Android代码-安卓开发学习资料和对应Demo

    Android学习路线总结,绝对干货 逆流的鱼的博客 汇总优秀的android开发资源 Android学习资源网站索引大全 Android Studiod的配置大全 深入理解Android的startservice和bindservice Android Studio权威教程专栏 各种...

    GradlePlugin:android自定义gradle插件项目

    其中很多都使用到了在编译时进行代码处理,大多数都是使用了自定义的gradle插件技术,所以一直比较好奇这个gradle插件是如何实现,经过学习和实践之后特此做一个总结 实现 1.创建plugin工程 AS中是没有专门的plugin...

    JcyDemoList:本项目有用的框架,架构总结和自定义控件以及源码等学习-项目

    BaseLibrary:基类-子模块,本人总结的开发基Moudle,包括初始化,基类,联网,工具类等等 CustomWidget:自定义组件,学习HenCoder练习项目集锦,以及自己的综合练习demo HttpServer:Android本地的微型服务器,...

    AndroidStudy:Android学习过程的一些总结

    Gradle理论与实践一:Gradle入门 ( ) Gradle理论与实践二:Groovy介绍 ( ) Gradle理论与实践三:Gradle构建脚本基础 ( ) Gradle理论与实践四:自定义Gradle插件( ) Gradle配置中subprojects和allpr

    springboot简单总结

    springboot学习路程中有关的资料,创建独立Spring应用程序,嵌入式Tomcat,Jetty容器,无需部署WAR包,简化Maven及Gradle配置,尽可能的自动化配置Spring,直接植入产品环境下的实用功能,比如度量指标、健康检查及...

    93个netty高并发教学视频下载.txt

    93个netty高并发全面的教学视频下载,每个视频在400-700M,一到两个小时时长的视频,无机器码和解压密码,下载下来的就是MP4格式视频。点击即可观看学习。下载txt文档,里面有永久...92_精通并发与Netty课程总结与展望

    Android开发2019(很好很详细)ppt

    Android开发ppt,2019年辛苦整理的最新版,基本上是最新版也是最实用的。2019年春上课用的课件,使用...Android Studio的gradle使用的是3.0版的。唯一的缺憾就是没有介绍最新的Android框架,所以适合Android学习入门。

    精通并发与netty视频教程(2018)视频教程

    1_学习的要义 2_Netty宏观理解 3_Netty课程大纲深度解读 4_项目环境搭建与Gradle配置 5_Netty执行流程分析与重要组件介绍 6_Netty回调与Channel执行流程分析 7_Netty的Socket编程详解 8_Netty多客户端连接与通信 9_...

    精通并发与 netty 视频教程(2018)视频教程

    精通并发与netty视频教程(2018)视频教程 netty视频教程 Java视频教程目录: 1_学习的要义 2_Netty宏观理解 3_Netty课程大纲深度解读 4_项目环境搭建与Gradle配置 5_Netty执行流程分析与重要组件介绍 6_Netty回调与...

    精通并发与netty 无加密视频

    第1讲:学习的要义 第2讲:Netty宏观理解 第3讲:Netty课程大纲深度解读 第4讲:项目环境搭建与Gradle配置 第5讲:Netty执行流程分析与重要组件介绍 第6讲:Netty回调与Channel执行流程分析 第7讲:Netty的...

    xmljava系统源码-XTCLint:实现Android自定义Lint实践(CustomLintRules&LintPlugin)

    这个是基于当时Gradle2.x系列写出来的自定义Lint实践总结,过去大半年了,现在将它搬到CSDN博客分享给大家一起学习学习。如果要在Gradle3.x系列使用该自定义规定的话,部分代码都得修改成最新的语法,因此此篇博客的...

    详解Android权限管理之RxPermission解决Android 6.0 适配问题

    上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxPermission。这里不再介绍Android 6.0运行时权限了,...

    Studio 编译报错:compileSdkVersion ‘android-24’ requires JDK 1.8 or later to compile.的解决办法

    报错翻译: compileSdkVersion android-24”...以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对软件开发网的支持。如果你想了解更多相关内容请查看下面相关链接

    高级java笔试题-AndroidCollectionResource:收集了大量文档的一个流行的android资源排序总结

    学习资源精选仓库 4.Tiny style-controlled SVG iconset 5.stackoverflow上Java相关回答整理翻译 6.ADB Usage Complete / ADB 用法大全 7.Android 开发中的日常积累 8.some code tips in android 9.Android开发的...

    阿里巴巴面试题leetcode-student_books:我的学习书库

    系列课程总结) Axure RP 指南 - v1.1.pdf Docker —— 从入门到实践 - v1.0 Git 教程 - v1.0.pdf (感觉 也挺好可以查看) GitHub 使用手册 - 基础篇 Gradle 实战中文版 - v1.0 Hibernate 教程 - v1.0.pdf IntelliJ ...

Global site tag (gtag.js) - Google Analytics