项目使用gradle进行构建,免去了xml配置的繁琐,同时也比maven拥有更多的功能点和自由度。
因为gradle是基于Groovy声明的配置,如果能掌握groovy语法,阅读教程将会事半功倍。
Groovy语法初探
这里不提供groovy的教程,只是为了更好地理解gradle中的部分语句。
主要介绍Groovy你可能会用到的一些特点:
变量类型推断,Groovy中定义变量可以像java那样声明变量类型,也可以像js那样,使用def定义一个变量,让其根据上下文自动定义变量类型:
def a="hello,world" println a //可直接使用println向控制台输出
特殊的数组定义方法,可以利用..表示一串相连的数字:
def range = 0..4 println range.class assert range instanceof List //groovy中的断言可用来判断一个表达式是否为true //这里定义了一个0 1 2 3 4的List
类似地,可以在循环中使用:
for(i in 0..5){ println i }
闭包,groovy有闭包的语法,其实就是一个匿名代码块,可以有返回值,也可以作为参数在代码间传递,闭包的参数和执行语句需要用“->”分离开来,以下是一些闭包的例子:
def a={ println it //it是闭包自带参数,代表着它本身 return "hello,world" } def b={ value -> valu="hello" return value }
基本操作
先来看一个最基本的gradle.build(注意。这一脚本的部分内容已经过时了):
apply plugin: 'java' apply plugin: 'war' //各任务编译编码为utf-8 [compileJava, compileTestJava, javadoc]*.options*.encoding = 'utf-8' sourceCompatibility = "1.7" targetCompatibility = "1.7" //配置依赖 使用maven的阿里云仓库(优先使用本地仓库)注意:先决条件是maven repositories { mavenLocal() maven{ url "http://maven.aliyun.com/nexus/content/groups/public/" } } //添加jar包依赖 dependencies { //仅在编译的时候需要,但是在运行时不需要依赖 providedCompile "javax.servlet:javax.servlet-api:3.1-b07" compile 'commons-pool:commons-pool:1.6' compile 'org.apache.commons:commons-pool2:2.4.2' compile 'org.springframework:spring-context:3.2.5.RELEASE' compile 'org.springframework:spring-web:3.2.5.RELEASE' compile 'org.springframework:spring-tx:3.2.5.RELEASE' compile 'org.springframework:spring-aop:3.2.5.RELEASE' compile 'org.springframework:spring-webmvc:3.2.5.RELEASE' compile 'com.alibaba:druid:1.1.8' compile 'log4j:log4j:1.2.17' testCompile 'junit:junit:4.11' } //指定源码目录和资源目录 sourceSets{ main{ java.srcDirs=['src','resource'] resources.srcDirs=['db'] } } //war打包 war{ from('WebRoot') { exclude 'WEB-INF/lib' } //复制非java资源,如xml、properties等 from('src') { exclude '**/*.java' into 'WEB-INF/classes' } from('resource') { into 'WEB-INF/classes' exclude 'logback.xml' } from('resource') { into 'WEB-INF/classes' include 'logback.xml' filter { it.replace('DEBUG', 'INFO') } } } // 从依赖关系导出jar包到war的lib包 task downloadJar(type: Copy) { from configurations.runtime into 'WebRoot/WEB-INF/lib' }
以上是利用gradle将java项目打包为war的脚本配置,gradle能实现的远不止于此。接下来介绍gradle的模块们。
项目布局定义
类似于maven的骨架,不是所有的项目都采用java原生的布局:
更多时候,我们需要定义项目的目录结构,这时可以在sourceSets中定义(这是java插件中的内容):
//way1 sourceSets{ main{ java.srcDirs=['src','api','thirdparty','fastdfs'] //数据库脚本所在目录需要单独处理 resources.srcDirs=['db/product'] } } //way2 sourceSets{ main{ java { exclude '/test/**' // 去除掉不包含的路径 } resources { srcDir 'src/resources' // 指定源码的目录 } } }
定义仓库和导入依赖
在gradle中可以定义多个仓库,定义在repositories的闭包中,如下使用maven本地库和指定url的maven库,gradle将根据定义仓库的先后顺序寻找依赖包:
repositories { mavenLocal() //maven本地库 maven{ url "http://maven.aliyun.com/nexus/content/groups/public/" } }
在dependencies闭包中定义依赖:
//添加单个依赖 compile 'log4j:log4j:1.2.17' /* 闭包形式,以添加额外配置*/ compile ('log4j:log4j:1.2.17){ //其他配置 }
描述一个依赖的内容包括group、name和version,也可以使用fileTree引入项目目录下的依赖:
compile fileTree(dir: 'WebRoot/WEB-INF/lib', includes: ['*.jar'])
主要使用以下依赖:
implementation:隐藏在内部的依赖(外部项目无法调用本依赖)
api:源代码编译依赖
compileOnly:编译依赖,但是不参与打包(同providedCompile)
runtimeOnly:仅在源代码运行时依赖
testImplementation:测试代码编译依赖,同样隐藏在内部
testRuntimeOnly:仅在测试代码执行依赖
archives:项目打包依赖
在旧版本中,主要使用如下依赖:
compile:源代码编译依赖,是旧版本最常用的依赖(同api);
runtime:源代码执行的依赖;
testCompile:测试代码编译依赖;
testRuntime:测试代码执行依赖;
providedCompile:编译依赖,但是不参与打包;
archives:项目打包依赖;
gradle更新依赖类别不是没有道理的,新项目中一般都是模块独立的,为了更好地解耦,提高打包执行效率,我们建议只打包需要的部分,而且在新版本的gradle中应尽量少使用旧版本的依赖类型,例如用implementation依赖取代api或是compile依赖。
定义一个任务
通过task可以定义一个具体的任务:
task copyTo(type: Copy, group: "Custom", description: "Copies sources to the dest directory") { from "src" into "dest" }
我们定义了一个copyTo任务,并定义了type为Copy(相当于继承),在gradle中已经定义了Copy这一任务,我们可以 直接依此实现拷贝文件树的操作。
type、group、description等参数都可以不定义。
然后通过如下命令执行它:
gradle copyTo -refresh-dependencies
其中–refresh-dependencies表示强制刷新。
添加插件
类似于maven,gradle也内置了很多插件,通过如下命令添加插件:
plugins { id 'org.hidetake.ssh' version '2.9.0' }
这是用来自动拉取打包文件并上传至服务器的的ssh插件,因为gradle版本的问题,在2.0之前的版本,只能使用如下的语法添加插件:
buildscript { repositories { maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "org.hidetake:gradle-ssh-plugin:2.9.0" } } apply plugin: "org.hidetake.ssh"
上面的写法直接自动从中心库中拉取了ssh的插件,而旧版本则是先拉取再导入插件。