gradle替代maven

来源:互联网 发布:淘宝网卖家注册 编辑:程序博客网 时间:2024/06/03 20:53
摘要: 厌倦了maven的繁杂,试玩一下传说中的下一代构建工具

工具版本:Gradle:2.2.1 Groovy:2.3.6 JVM:1.6.0_43 maven已经成为java web开发的标配,下面是一个常见的java web工程:

maven工程目录 usercenter包含两个工程,app是web工程,common是公共模块,但是app的main目录下除了java、resources、webapp之外又多了一个native2ascii的资源目录,严格来说这不符合maven约定,不过没关系,gradle除了支持maven的约定外还允许自定义java或者resources目录

下面是gradle主配置文件(删除了大部分无关紧要的依赖,能说明问题即可)

<!-- lang: groovy -->// gradle插件buildscript {    repositories {        jcenter { url "http://jcenter.bintray.com/" }    }    dependencies {        // 远程布署插件        classpath 'org.hidetake:gradle-ssh-plugin:1.0.1'        // web容器,支持jetty和tomcat        classpath 'org.akhikhl.gretty:gretty:1.2.0'    }}// 全局配置,对所有工程有效allprojects {  apply plugin: "java"  apply plugin: "idea"  apply plugin: "eclipse"  apply plugin: "maven"  group = "com.test"  version = "1.0"  // 全局属性设置  ext {    junitVersion = "4.11"    springVersion = "3.0.5.RELEASE"    // java文件编码方式设置为utf-8    compileJava.options.encoding = 'UTF-8'    compileTestJava.options.encoding = 'UTF-8'  }}// 所有子工程共有的配置subprojects {  // 配置多个maven源  repositories {      mavenLocal()      mavenCentral()      maven { url "http://mirrors.ibiblio.org/pub/mirrors/maven2" }  }  // 默认情况下gradle会选用版本最高的那个依赖,有时候会带来问题  configurations.all {    // 有版本冲突的时候强制使用指定的版本,对于相关依赖也同样有效    resolutionStrategy.force(      "org.springframework:spring-core:${springVersion}",     )  }  // 公共依赖配置  dependencies {      compile(        "org.springframework:spring-core:${springVersion}",      )      testCompile(        "junit:junit:${junitVersion}",      )  }}// app工程配置project(':app'){  apply plugin: 'war'  apply from: 'gretty'  // 使用gretty插件运行web工程  gretty {    httpPort = 8080    debugPort = httpPort + 1    servicePort = httpPort + 2    statusPort = httpPort + 3    httpsPort = httpPort + 4    httpsEnabled = true    contextPath = '/'    jvmArgs = ['-Xmx1024M', '-XX:PermSize=128M', '-XX:MaxPermSize=256M']    servletContainer = 'jetty7'    scanInterval = 0    inplaceMode = 'hard'    debugSuspend = false  }  // 自定义resource文件夹  sourceSets {    main {      resources.srcDirs = ['src/main/resources', 'src/main/native2ascii']    }  }  dependencies {    compile(      // 依赖common工程      project(":common"),      "javax.servlet.jsp:jsp-api:2.1",      "javax.servlet:servlet-api:2.5",    )  }}// common工程配置project(':common'){  // 设置resource文件目录,引入java文件夹下的xml文件  sourceSets {    main {      resources.srcDirs = ['src/main/resources', 'src/main/java']      resources.includes = ['src/main/java/**.xml']    }  }  dependencies {    compile(      "org.mongodb:mongo-java-driver:2.10.1",      fileTree(dir: 'lib' , include: '*.jar' )    )  }}

settings.gradle中记录子工程,内容只有一行

include 'app','common'

可以把gradle配置写到多个文件夹下,每个子工程都下都新建一个build.gradle,如果工程比较简单,也可以像上面样,所有子工程的配置都写到主工程的build.gradle

运行的时候只需要在主工程的目录下执行一个命令即可

> gradle app:jettyRun

maven相似,gradle也是以插件的形式来扩展功能,新增插件 apply plugin: 'jetty' ,每个插件有配置都是以代码块的形式提供,上面的配置中使用的gretty配置web容器,gretty的配置块是:

  gretty {    httpPort = 8080    debugPort = httpPort + 1    servicePort = httpPort + 2    statusPort = httpPort + 3    httpsPort = httpPort + 4    httpsEnabled = true    contextPath = '/'    jvmArgs = ['-Xmx1024M', '-XX:PermSize=128M', '-XX:MaxPermSize=256M']    servletContainer = 'jetty7'    scanInterval = 0    inplaceMode = 'hard'    debugSuspend = false  }

配置简单易懂,无需多讲

这里gretty配置了jetty7做为web容器,gradle自带jetty插件(不支持java代码热布署,只能更新jsp等),配置如下:

// jetty启动配置jettyRun {    httpPort = 8080    contextPath = ""    reload = "automatic"    scanIntervalSeconds = 1}

上面是简单的替代maven,显然gradle能做的不只这些,得益于groovy的轻巧,gradle提供了强大的灵活性。下面看一个应用场景。

使用 org.hidetake.ssh 插件,可以把本地的war包发布到远程服务器。在 build.gradle 头部加入如下配置

// 在gradle脚本build之前起作用buildscript {    repositories {        jcenter()    }    dependencies {        classpath 'org.hidetake:gradle-ssh-plugin:1.0.1'    }}

buildscript用于配置不在maven仓库的插件,它在gradle脚本运行之前执行。

ext块中配置服务器:

// 远程服务器地址tomcatPath = '/opt/tomcat'// 远程服务器地址remotes {    server {        host = '192.168.1.1'        user = 'root'        password = 'root'    }}

通常本地开发环境与服务器环境是不一致的,比如本地开发用的端口号是8080,远程服务器使用的域名和端口都不一样(由nginx转发请求),如果要在发布到远程服务器的时候替换配置文件中的域名,就可以这样。

先在ext块中配置域名对应关系

replaceUrl = [    'myapp:8080' : 'myapp:7654',    'mypartner:9090' : 'mypartner:7655',]

再在project(':common')块中配置执行jar包阶段替换*.properties配置文件中的域名

// 如果是deploy到远程服务器,打包的时候替换域名jar {    def replace = false    project.gradle.startParameter.taskNames.each{ command ->        if(command.contains('deploy')){            replace = true        }    }    if(replace){        filesMatching('**/*.properties') {            filter{                // it变量是filter迭代器中的默认名称,这里代表每一行                def result = it                replaceUrl.each{ key,value ->                    if(it.contains(key)){                        result = result.replaceAll key, value                    }                }                result            }        }    }}

这段代码是原生的groovy代码了,gradle的灵活性就体现在这里了,关于groovy语言,大家自行脑补。

project.gradle.startParameter.taskNames是gradle命令行参数,如gradle clean app:deploy,那么命令行参数就是['clean', 'app:deploy']

filesMatching('**/*.properties') 是过滤所有的以properties结尾的文件,**是递归查找。接下来是布署代码了:

// 布署至远程服务器,上传的war名为app.wartask deploy(dependsOn: war) << {  ssh.run {    session(remotes.server) {        put "$war.archivePath.path", "$tomcatPath/webapps/app.war"        execute "$tomcatPath/bin/shutdown.sh"        execute "rm -rf $tomcatPath/webapps/ROOT/*"        execute "unzip -oq $tomcatPath/webapps/app.war -d $tomcatPath/webapps/ROOT"        execute "rm -f $tomcatPath/webapps/app.war"        execute "$tomcatPath/bin/startup.sh"    }  }}

deploy只是简单的执行shell命令,上传war包,关闭tomcat,解压war,删除war,启动tomcat。 布署命令:gradle clean app:deploy

0 0