gradle总结实战

来源:互联网 发布:网络文明手抄报内容 编辑:程序博客网 时间:2024/06/01 07:38

概述

gradle跟maven是很类似的,但是他写起来比maven简洁,所以力荐使用gradle来构建我们的项目,而且gradle使用groovy开发的,所以gradle能够书写逻辑,但是maven这方便就很弱了,下面就来看看gradle。

基本

使用java插件

就像maven里的插件一样,gradle也有插件概念,但是这里引入插件就很简洁,只需要一行。

apply plugin:'java' //该插件会去src/main/java下找源代码,并打包生成build文件夹,里面有很多生成的资源

设置gradle支持utf-8

gradle版本的差异,有可能存在不支持汉字,所以这里配置支持UTF-8,最好每次构建项目,都配置上。

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

定制项目

项目编译jdk版本设置,有了这个属性,更换不同版本jdk进行编译就变得非常简单,比如:我电脑安装的是jdk8,但是我为了打成jar包兼容低版本的项目,以前我们的做法是,在电脑上安装多个jdk然后修改环境变量进行切换,现在不用那么麻烦,你只需要讲下面的两个属性sourceCompatibility,targetCompatibility都设置1.7,这样即使真是环境是jdk8,但是编译后的class是jdk7的环境的。

version = 0.1       //项目版本//设置java版本sourceCompatibility = 1.7targetCompatibility = 1.7
jar{                    manifest {          attributes 'Main-Class':'com.robin.demo'    //在jar包的MANIFEST.MF里添加属性(这里是运行的主类)    }}

结构定制

maven 的标准目录结构,大家应该有一定印象吧!src/main/java/* , src/main/resources/, src/test/java/ 等等,但是有些项目的特殊性,这里支持结构的定制(一般不要修改,按照默认的标准就可以)。

//改变默认的目录结构sourceSets {    main{        java{            srcDirs = ['src']   //默认的源码结构是src/main/java,这里修改成了src        }    }    test{        java{            srcDirs = ['test']  //默认的源码结构是src/test/java,这里修改成了test        }    }}

问题:

将src/main下的generated文件夹修改为类路径,如何在geadle里设置脚本?马上想到的解法:

sourceSets {    main {        java {            srcDirs = ['src/main/generated']        }    }}

上面的写法是错误的,为何?因为这样设置,会将源码的目录设置成了generated,而原来的src/main/java目录就失效了,不是资源目录了。正确的写法是:

sourceSets {    main {        java {            srcDirs += 'src/main/generated'        }    }}

解释:srcDirs这个属性的类型是数组,如果要改变的话就直接=[’ ‘],这样就改变整个数组的值,而 +=’ ’ 是向数组里添加值。

排除一些资源

某些class不想打进jar包里去,或者war包里去,如何做?

sourceSets {    main {        java {            exclude 'com/robin/demo'    //这样com.robin.demo包下的所有类都不会打进jar下        }    }}

问题:

我们在src/main/java/**.xml的mybatis映射文件打包到war包下的classes下会失败,如何将解决?
1. 方式一:
在resources资源目录下新建com/robin/**.xml文件,这样打包会打到classes下的。
2. 方式二:将src/main/java/**.xml配置成资源目录,在build.gradle里添加:

sourceSets {    main {        resources {             //这里的srcDir是方法,上面的是属性            srcDir 'src/main/java' //可以将java目录下的所有非.java资源打包到classes下        }    }}

输出定制

输出定义:

buildDir = 'out'    //定义输出路径,原来的是build文件夹下的

定义仓库

默认使用的maven仓库下载jar,但是速度就…这里给出如何配置私服,下面的给出的是配置aliyun的私服地址。

repositories{    jcenter()    maven {        url 'http://maven.aliyun.com/nexus/content/groups/public'--修改成阿里云的仓库    }    mavenCentral()}

定义依赖

重头戏来了,开始怎么引入jar包了,也就是配置依赖。下面的第一行compile是完整写法,第二个compile是简写。

dependencies {    compile group:'org.apache.commons', name:'comcc', version:'3.1'    compile 'org.apache.commons:comcc:3.1'      --上下等价,下面是简写}

消除依赖

在项目构建的时候经常发生jar冲突问题,此时如何消除依赖了,下面给出消除依赖的方法。

compile ("com.alibaba:dubbo:${dubboVersion}") {    exclude group: "org.springframework"    exclude module: "comcc" // name所对应的    exclude group: "", module: "" //可以更加详细}# exclude group: groupName

web部分

war插件的使用

进行war包构建相关的逻辑,需要引入war这个插件。

apply plugin: 'war' --这个插件主要应用与web下开发的,并且自扩展java插件

结构:

一个web项目的标准结构,如下:

|   ---build.gradle|---src    |    --main        |        ---java/..        |        ---resources/..        |           ----webapp            |            ---WEB-INF/web.xml            |            ---css/..

依赖域

有的依赖是不需要跟war打在一起的,那么就可以使用providedCompile.

dependencies {    providedCompile 'javax.servlet:servlet-api:2.5'     --这个依赖由容器(例如tomcat)提供,这里会有jetty提供,他不会打包到war包里面    runtime 'javax.servlet:jstl:1.1.2'      --jstl这种依赖,编译时不需要,运行时需要,会成为war包的一部分}--运行后会在build/libs下有个war包

定制web项目

下面是一个非标准结构的web项目,我们如何对下面的结构进行定制了?

|--build.gradle|--src|  ||   --main/java||---static|      ||      --css|----webfile    |    --WEB-INF/web.xml    |    ---jsp/..

写法:

webAppDirName = 'webfile'   --默认属性是src/main/webappwar{    from 'static'}

添加多个war资源目录,由于from的参数是from(Object…obj),所以用可变参数结构来添加:

war {    from 'static01', 'static02', ...}

jetty插件的使用

开发阶段,我们可以使用jetty作为web容器,进行开发,速度快,便捷。下面通过插件引入,很简洁

apply plugin: 'jetty'

运行指令:

gradle jettyRun (即使没有jar包也能跑起来)

给jetty配置属性:

jettyRun {    httpPort = 80       --修改jetty运行的端口号    contextPath = 'todo'    --修改应用名}//  http://localhost:80/todo

常用补充

我们在使用Project和Task类时,这里已经为我们提供了默认的对象,我们只需要调用方法即可

version '1.0'   --调用Project里的setVersion(..)方法的

当然我们可以在build.gradle里定义自己的外部属性,然后直接引用自己定义属性,通过ext命名空间:

ext {    vertxVersion = "3.1.2"}

使用:

compile "io.vertx:vertx-core:${vertxVersion}"--这里一定要用""来引起字符串,不要用'',否则${vertxVersion}就变成了字符串而不会被转义

建议:
尽量使用” “而少使用’ ‘

自定义task

定义任务 关键字 task 【任务名】

--定义任务task print{    doFirst {        println "01"    }    doLast {        println "02"    }}

doFirst和doLast正如名字一样,一个先执行,一个后执行。下面是向已经定义的任务里添加动作(doFirst类型的话,会向顶部添加,doLast的话,会向底部添加)。

print.doFirst {    println "03"}print.doLast {    println "04"}

将自己的任务加入到gradle生命周期的一个标准任务里。

build.doFirst {    //...}

gradle基于SLF4J实现了一个日志

task printVersion<<{    logger.info("Version:$version")}

dependsOn任务依赖

可以在一个任务里,依赖多个任务,执行run之前,会先执行[two, first] ,这里two, first这两个任务执行没有顺序。

task first<<{    println "one"}task two<<{    println "two"}task run(dependsOn:[two, first]) {}

另一种添加依赖的方式:

task third {    println "third"}third.dependsOn("run")

finalizedBy指定下一个任务

上面[two, first]没有顺序,可以使用finalizedBy强行指定顺序。

task first<<{    println "one"}task two<<{    println "two"}two.finalizedBy first

任务配置块

task run {    print("hello")}

随便运行gradle build/gradle clean…都会执行run这个任务块,这就是任务配置块
为何他总会执行?
要从gradle的构建生命周期来解释,每个任务执行都会经历:初始化、配置、执行,三个阶段,
所以配置块在第二阶段会执行
配置任务快执行是有一定顺序的,当任务A依赖任务B,则A->B的。

gradle的多项目构建

在一个项目里创建几个子项目

结构为:

rootPrject|---sub01|       ||       ----src/main/java---sub02|       ||       ----src/main/java---subWeb|       ||       ----src/main/java---build.gradle|---settings.gradle

在settings.gradle文件里设置:

include 'sub01', 'sub02', 'subWeb'

或者

include 'sub01'include 'sub02'include 'subWeb'

注意:setings.gradle会在构建初始化阶段执行。

在根项目下配置gradle的逻辑:

ext.projectIds = [group:"com.robin", version:"1.0-SNAPSHOT"]group = projectIds.group;version = projectIds.versionproject(":sub01") { //每个子模块也是一个项目,:是路径,我们可以申明sub/sub001下的sub001位一个子项目,此时写法是project(:sub:sub001)    group = projectIds.group;    version = projectIds.version    apply plugin: "java"}project(":sub02") {    group = projectIds.group;    version = projectIds.version    apply plugin: "java"}project(":subWeb") {    group = projectIds.group;    version = projectIds.version;    apply plugin: "war"    apply plugin: "jetty"    repositories {        mavenCentral();    }    dependencies {        providedCompile "javax.servlet:servlet-api:2.5"        runtime "javax.servlet:jstl:1.1.2"    }}

每个项目都有group和versin属性,上面的做法是将group和version的值放入list集合然后添加到ext域里去,这样才能被其他模块引用。一般我们将其他模块需要引用的变量,我们会放入到ext里去的。

项目之间的依赖

一般子项目sub01和sub02会打成jar包的,而subWeb的子项目会打成war包的,并且subWeb项目会依赖sub01、sub02这两个项目。下面我们来生命项目之间的依赖:

project(":sub01") {    ...    apply plugin: "java"}project(":sub02") {    apply plugin: "java"    //一定要加上这个,否则项目之间的依赖会出错    dependencies {        compile project(':sub01');   //编译时依赖sub01    }}project(":subWeb") {    apply plugin: "war"    apply plugin: "jetty"    repositories {        mavenCentral();    }    dependencies {        providedCompile "javax.servlet:servlet-api:2.5"        compile project(":sub02")        runtime "javax.servlet:jstl:1.1.2"    }}

使用allProjects和subProjects来构建公共项目块:

allprojects {       //所有的项目都共有,包括根项目和子项目    group = "com.robin"    version = "1.0-SNAPSHOT"}subprojects {   //所有的子项目包含java插件    apply plugin: "java"}

将子项目的构建脚本也写在根build.gradle写显示不是好的选择,可以在每个子项目下创建一个build.gradle文件。

  • 以后根build.gradle下只有:
allprojects {       //所有的项目都共有,包括根项目和子项目    group = "com.robin"    version = "1.0-SNAPSHOT"//    apply plugin: "java"  //若是这里加了java插件,那么跟项目下的src目录也是起作用,所以不建议添加在此处}subprojects {    apply plugin: "java"    sourceCompatibility = 1.8    repositories {        mavenCentral()    }    dependencies {        testCompile group: 'junit', name: 'junit', version: '4.12'    }}
  • 子项目subWeb的build.gradle下有:
apply plugin: "war"apply plugin: "jetty"dependencies {    providedCompile "javax.servlet:servlet-api:2.5"    compile project(":sub02")    runtime "javax.servlet:jstl:1.1.2"}

其他的子项目也是类似的。

gretty插件

apply plugin: 'org.akhikhl.gretty'gretty {    servletContainer = 'tomcat8'    httpPort = 80    contextPath = ""    debugSuspend = false}buildscript {    repositories {        jcenter()    }    dependencies {        classpath 'org.akhikhl.gretty:gretty:+'    }}

gradle打包常用任务

def replace(fileName, map) {    def fl = file(fileName)    def content = fl.getText("UTF-8")    map.each { k, v -> content = content.replace(k, v) }    fl.write(content, "UTF-8")}def cp(source, dest) {    file(dest).write(file(source).getText("UTF-8"), "UTF-8")}

gradle插件开发

开发工具:idea, gradle

新建工程:

在idea里新建root工程plugins, 修改build.gradle

allprojects {    group 'com.robin'    version '1.0-SNAPSHOT'}subprojects {    apply plugin: 'groovy'    repositories {        maven {            url "http://nexus.nxin.com/nexus/content/groups/public/"        }        mavenCentral()        jcenter()    }    dependencies {        testCompile group: 'junit', name: 'junit', version: '4.12'    }}

新建子工程

新建gradle groovy的plugin01子工程,其build.gradle为:

//插件坐标group 'com.nxin'version '1.2'apply plugin: 'maven'uploadArchives {    repositories {        mavenDeployer {            //测试,打包到本地            repository(url: uri('../repo'))        }    }}dependencies {    compile gradleApi()}

在src/main/groovy下新建com.robin.demo.HelloPlugin.groovy类:

package com.robin.demoimport org.gradle.api.Pluginimport org.gradle.api.Project/** * Created by robin on 2017/1/12. */class HelloPlugin implements Plugin<Project> {    @Override    void apply(Project project) {        project.task('hello') {            println "HelloWorld";        }    }}

给插件指定简短别名

方便 apply plugin: shortName r;在resources下新建META-INF/gradle-plugins/hello.properties,hello就是shortNmae,hello.properties里的内容为:

implementation-class=com.robin.demo.HelloPlugin 

打包

然后在子工程下打包,执行:

gradle -q upload    //打包成jar

新建测试子模块 testHelloPlugin,build.gradle为:

group 'com.robin'version '1.0-SNAPSHOT'buildscript {    repositories {        maven {            url uri('../repo')        }    }    dependencies {        classpath 'com.nxin:plugin01:1.2'    }}apply plugin: 'hello'repositories {    mavenCentral()}dependencies {//    compile 'org.codehaus.groovy:groovy-all:2.3.11'//    testCompile group: 'junit', name: 'junit', version: '4.11'}

在子模块中运行 gradle hello

1 0
原创粉丝点击