1 Groovy
1.1 基础
==相等于equals(),不会有NPE
弱类型
class ProjectVersion{
2 private int major
3 private int minor
4 5
ProjectVersion(int major,int minor) { //默认都是public可以不写
6 this.major = major;
7 this.minor = minor;
8 }
9 }
10
11 ProjectVersion v1 = new ProjectVersion(1,1)
12 println v1.minor
13
14 ProjectVersion v2 = null
15 println v2 == v1 //false 没有报出NPE
16
17 //1 可选的类型定义(⾃动推断)
18 def version = 1
19
20 //2 assert
21 //失败的断⾔
22 //assert version == 2 //在groovy⾥ assert在任何地⽅都可以执⾏
23
24 //3 括号是可选的
25 println(version)
26 println version
27
28 //4 字符串
29 def s1 = 'lane' //单引号就是普通字符串
30 def s2 = "lane is ${version}" //双引号可以嵌⼊变量
31 def s3 = '''my name is
32 lane'''//三个单引号可以换⾏
1Groovy
1.1基础33
34 println s1
35 println s2
36 println s3
37
38 //5 集合api
39
40 //list 对应的是ArrayList
41 def buildTools=['ant','maven']
42 buildTools << 'gradle' //追加⼀个元素
43 assert buildTools.getClass() == ArrayList
44 assert buildTools.size() == 3
45
46 //map 对应的是HashMap
47 def buildYears= ['ant':2000,'maven':2004]
48 buildYears.gradle = 2009
49
50 println buildYears.ant
51 println buildYears['gradle']
52 println buildYears.getClass()//class java.util.LinkedHashMap
53
54 //6 闭包
55 //⼀个代码块,可以有参数也可以没参数,可以被赋值给⼀个变量,也可以当作参数传递
56 def c1 = {
57 v ->
58 println v
59 }
60
61 def c2 = {
62 println 'hello'
63 }
64
65 def method1(Closure closure) {
66 closure('param')
67 }
68
69 def method2(Closure closure) {
70 closure()
71 }
72 method1(c1)
73 method2(c2)
一个简单脚本
1 // 构建脚本中默认都是有个Project实例的2 //构建脚本中所有代码作⽤域都是Project
3 apply plugin:'java' //apply(plugin:'java') 命名参数 省略了括号
4 version = '0.1'
5 repositories{
6 mavenCentral()
7 }
8 9
dependencies{
10 compile 'commons-codec:commons-codec:1.6'
11 }
12
13 ----------
14 plugins {
15 id 'java'
16 }
17
18 group 'com.lane..gradle'
19 version '1.0-SNAPSHOT'
20
21 repositories {
22 mavenCentral()
23 }
24
25 dependencies {
26 testCompile group: 'junit', name: 'junit', version: '4.12'
27 }
1.2 第一个
1 打包 跟maven差不多:
2 构建脚本
2.1 构建块
项目(project)、任务(task)
每个构建至少包含一个项目,项目中包含一个或多个任务
在多项目构建中,一个项目可以依赖于其他项目,类似的,任务可以形成一个依赖关系来确保他们的执行顺序。
2.2 project
一个project代表一个正在构建的组件(比如一个jar包),Gradle会基于build.gradle实例化一个org.gradle.api.Project类,并能通过project变量使其隐式可用。
属性:group、name、version,这三个属性可以唯一确定一个组件(jar包)name就是maven里的ArtifactID
方法:apply、dependencies、repositories、task(声明项目里有什么任务的)
属性的其他配置方式:ext、gradle.properties
2.3 task
任务对应org.gradle.api.Task.主要包括任务动作和任务依赖。
任务动作定义了一个最小的工作单元,可以定义依赖于其他任务、动作序列和执行条件。
方法:dependsOn(生命任务依赖)
doFirst、doLast<<(在任务列表/最后添加一个任务)
一个项目中任务不是必须的,一般来说不用自己定义,插件自己有很多任务。
2.4 自定义任务
创建一个创建目录的任务
def createDir = {
2 path ->
3 File dir = new File(path)
4 if(!dir.exists()){
5 dir.mkdirs()
6 }
7 }
8 9
task makeJavaDir(){
10 def paths = ['src/main/java','src/main/resources','src/test/java']
11 //在动作列表前⾯插⼊⼀个动作
12 doFirst{
13 paths.forEach(createDir)
14 }
15 }
16 task makeWebDir(){
17 dependsOn(makeJavaDir)//先执⾏makeJavaDir
18 def paths = ['src/main/webapp','src/test/webapp']
19 //在动作列表前⾯插⼊⼀个动作
20 doLast{
21 paths.forEach(createDir)
22 }
23 }
自定义任务在Other目录下
3 构建生命周期
主要有三个阶段:
初始化(根据脚本创建一个project,多项目中会初始化所有需要参与到构建中的project)
配置(根据配置代码(非动作代码)生成 Task的依赖顺序和执行顺序)
执行(执行动作代码,执行完后一个构建就完成了)
上面的自定义任务代码,除了doFirst,doLast都是配置代码
如果把dependsOn放在doLast里(也就是放在动作代码里)会报错,因为依赖关系在配置阶段就要确定了。
4 依赖管理
1 工件坐标:group、name、version
2 常用仓库:存放jar包的地方
- mavenLocal(本地仓库)/mavenCentral/jcenter
- 自定义maven仓库(私服)
- 文件仓库(不用)
3 依赖的传递性:
A依赖于B,B依赖于C,--》A依赖于C(版本冲突)
4 依赖阶段配置:
源代码阶段:compile、runtime
测试代码阶段:testCompile、testRuntime
编译时依赖的Jar包,运行时会依赖;只运行时依赖的,编译时不会依赖
源代码依赖的,测试代码依赖;只测试代码依赖的,源代码不会依赖。
例:测试代码依赖的jar包
- dependencies {
- testCompile group: 'junit', name: 'junit', version: '4.12'
- }
大多数情况下用的都是编译的依赖。
仓库私服写法
- maven{
- url '地址'
- }
5 版本冲突
1 查看依赖报告
2 排除传递性依赖
3 强制一个版本(gradle默认使用最高版本的jar包)
修改默认解决策略
- configurations.all{
- resolutionStrategy{
- failOnVersionConflict()
- }
- }
解决冲突:
1 排除传递性依赖(比如排除掉低版本的依赖)
2 强制制定一个版本
例子:
项目里已经添加了:slf4j-1.7.25,
然后添加了hibernate3.6.3,它依赖slf4j1.5.8
可以看到gradle帮我们默认了解决版本冲突(选择较高版本)
(怎么看:help-dependencies:
)
如果修改一下策略,发现版本冲突时就自动构建失败:
解决方法:
1 排除传递性依赖,排除Hibernate对slf4j的依赖
- compile (group: 'org.hibernate', name: 'hibernate-core', version: '3.6.3.Final'){
- exclude group:"org.slf4j",module:"slf4j-api"
- }
2 强制制定版本(也可以制定项目里还没有的版本 ,会自动倒导入的)
- configurations.all{
- resolutionStrategy{
- failOnVersionConflict()
- force 'org.slf4j:slf4j-api:1.7.25'
- }
- }
5 多项目构建
好的实践:项目模块化。
例子:配置练习,项目有三个模块:modle,repository,web
配置要求
1 每个模块都有java插件
2 web模块打包成war包(web才有war插件)
3 所有模块添加logback功能
4 统一配置group和version
实现:
1 在工程build.gradle下配置:
- plugins {
- id 'java'
- }
2 在web模块下build.gradle下配置:
- plugins {
- id 'war'
- }
web下的task出现了war
3 可以使用subprojects
- //配置要求3,为所有子模块添加logback功能,用allprojects也可以
- subprojects{
- dependencies {
- compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.2'
- }
4 前面提到group,version属性可在gradle.properties指明,新建gradle.properties放在根目录下,这样各个模块的build.gradle里的group和version也可删去了
如果想执行整个工程的任务,在根目录下task执行就行了,想执行某个模块,就在模块下面执行对应任务,如在web模块下执行jar (从这个任务顺序可以看出依赖关系)
6 自动化测试
Gradle如何发现测试代码的:(具体看使用的测试框架)
- 任何继承自junit.framework.TestCase 或者groovy.util.GroovyTestCase的类
- 任何使用@Runwith注解的类
- 任何至少包含一个被@Test注解的类
- public class TestTodo {
- @Test
- public void test() {
- System.out.println("test");
- }
- }
执行build任务,可以看到过程,:
测试结果可以看build下的reports
7 发布
步骤:
1 使用publish插件
- plugins {
- id 'java'
- id 'maven-publish'
- }
2 对发布进行配置
- publishing{
- publications{
- myPublish(MavenPublication){
- from components.java
- }
- }
- repositories {
- maven {
- name "myRepo"//仓库的名字自己取
- url "" //可以填私服地址
- }
- }
- }
3 执行发布任务
publishToMavenLocal 发布到本地仓库