Gradle是一个优秀的自动化构建工具,你只需遵循一定的规则,就能够非常轻松地构建出你想要的项目,不仅可以轻松地让构建好的项目跑在任何机器上,而且还可以轻松地和其他同学一起开发软件,听了之后是不是感觉超级神奇?下面我们来看看到底是怎么回事。
一. 创建一个java项目
1. 手动创建
让我们先从手写一个HelloWorld项目开始,这个项目只干一件事,在屏幕上打印出”HelloWorld”。注意这里是要构建一个项目,所以不单单只是编写一个java文件,编译成class运行就行了,我们还需要一些目录结构。
这里假设你已经知道了java里package的概念,即package和文件目录一一对应,假设我们的HelloWorld文件如下:
package com.wzt;
public class HelloWorld{
public static void main(String args[]){
System.out.println("Hello World!");
}
}
我们的这个HelloWorld类属于com.wzt这个包,那么我们最基本的目录结构应该是图1红色部分的样子
图1假设你刚好看过一点点工程目录的样子,知道还有一个src的目录,好的,我们就在工程的根目录下建立了这样一个目录结构。现在我们开始编译这个HelloWorld.java,使用javac命令,好的,我们顺利的在wzt目录下生成的对应的class文件,然后运行,没问题。但是总感觉乱乱的,class和java文件放在一起,分开好不好,javac倒是有一个-d的参数能够重新安置class,但是放在哪呢,随便吧,放在src目录下,于是我们在src目录下增加了一个class文件夹,里面放了我们的class文件,像是下图2的样子,
图2 图3这样的目录结构是不是看起来就好多了。这时候跟你一起学java的小明也做好了,他给你看他的demo,如图3的样子,这时候你们开始争吵,后来经验丰富的老王来了,他告诉你们生成的class路径也要和package一一对应,你就和小明说,这个规矩太麻烦了,我要在编译的时候指定这么多级的文件夹,万一漏了一级就不好了,而且就这么个简单的工程我和同桌小明都不同,我和他的编译命令都不一样,我的是这样的:
javac src/com/wzt/HelloWorld.java -d classes
而他的是这样的:
javac src/com/wzt/HelloWorld.java -d src/classes
就连这个都不能复用,后面我们还要把这个工程打成一个jar包,肯定也会有不同,蝴蝶效应啊,这真是个悲伤的故事。
老王说,那我们规定一个目录结构吧,然后把编译和打包的命令写成一个脚本,构建好了基本目录一运行脚本就行了。于是我们又做了一遍,果然不错,还是老王有经验。这时候老王跟你们说有一个工具叫Gradle,可以做上面说的这些事,并且做得更好,更多,这么神奇?等不了了,快上车。
2. Gradle构建
既然用别人的给的工具,到了别人的地盘上,就要守别人的规矩,好在所有人都遵循同一套规范,大家都一样的时候就会感觉没有区别了。好,我们现在建立图示这样一种目录结构,红色部
图4分依旧是由源文件的package决定的目录结构。绿色的部分是Gradle新增的文件,里面记录了工程的所有信息,让我们来看看这个工程需要哪些信息:
1. apply plugin : 'java'
2. jar {
3.manifest{
4.attributes 'Main-Class' : 'com.wzt.HelloWorld'
5.}
6. }
简单的第一行非常好用,意思是用了java这个插件,我们可以用gradle tasks看一下这个插件增加了哪些task,这里就不一一列举了。假设我们先就只在build.gradle中写第一行,然后运行gradle build命令,得到了很多任务的反馈信息,再看一下目录结构,发现在src平级的地方多了一个build文件夹,打开看看吧,发现里面有classes、libs等,我们就说这两个文件夹,classes里面是按照package名组织好的文件目录,libs里面是打包好的jar包。让我们来运行一下jar包,发生了这样的错误:
no main manifest attribute, in build/libs/jartest.jar
找不到manifest的参数,哪痛打哪,我们在build.gradle加上了2-4行,很好理解,我们在jar包中给manifest一个Main-Class的参数,即我们的类名,重新build之后运行jar包,发现成功打印除了HelloWorld!成功了!那我们现在来写一个web应用吧。
二. 创建一个java web项目
1. 手动创建
我们以一个简单的数据采集应用为例,网页让用户填写相关信息,用户填写完毕后保存到数据库。让我们先手动创建上述项目。首先手动建立一个标准的java web应用的目录结构,如图5,src目录下
图5是按package组织的java源文件。web文件夹是整个web应用,下面包括一个jsp页面(或jsp、css目录),WEB-INF文件夹,在WEB-INF下的classes存放class文件,lib下是外部依赖库。还需要一个web.xml来记录配置信息。
所有目录和源文件都准备和组织好之后,还有一个问题,还需要准备外部依赖的jar包,好了,这时候我们开始想办法弄这些jar包,好在这个项目需要的外部依赖只有两个,一个mysql相关,
图6另外一个servlet相关,经过拷贝和下载之后,我们终于把这些jar包放在lib文件夹中了。现在我们谢了一个脚本,编译源文件,指定输出的class目录,然后打包,生成war包。所以整个过程如图6。其中建立目录是个细活,不能出错,准备jar包是个力气活,如果项目里需要很多外部依赖的jar包,你就需要到每个jar包相关的网站上下载,是不是很麻烦。
最后当别人拿到你的war包之后,想要扩展,发现目录结构又不一样,又发生了我们之前说的那些问题。
2. Gradle构建
图7
与构建java项目类似,我们要遵循一定的规则构建目录,并编写build.gradle文件,当然,文件中的东西是不一样的,先给出目录结构,可以看到发生了些许变化,web应用文件夹被放在了src/main下面,web变成了webapp,并且不用在WEB-INF下手动创建classes和lib文件夹了。(见图7)
接下来我们来做最后一步。什么?最后一步,这就最后一步了,我手动构建时的jar包都准备好了,你跟我说不要了?对的,最后一步就是编写build.gradle文件,我们来看看这个build.gradle该怎么写:
1. apply plugin : 'java'
2. apply plugin : 'war'
3. repositories {
4.mavenCentral()
5. }
6. dependencies {
7.providedCompile 'javax.servlet:servlet-api:2.5'
8.runtime 'javax.servlet:jstl:1.1.2'
9.compile 'mysql:mysql-connector-java:5.1.6'
10.}
我们来一步步解释这个文件:
1. 插件 首先我们在第二行加了一个插件’war’,顾名思义,这个插件就是跟war包有关。
2. 代码仓库 接下来3-10行就是来解决jar包的,gradle提供的你想要的jar包也不是凭空来的,也不是gradle自动编写生成的,gradle也是通过代码仓库下载下来,gradle是基于Maven的,所以你需要3-5行的声明,告诉gradle你的仓库是什么,这里用的是Maven,如果你非常牛,经常开发一些自己的jar包并持续应用到项目中,那么你也可以提供一个本地的仓库或是其他仓库。
3. 配置依赖 6-10行配置项目中需要的依赖,也就是具体需要从第2步的代码仓库中下载哪些依赖包,这里因为不同的依赖需要的时间段不一样,有的是运行,有的是编译,所以你会看到dependencies里面不同的声明。
到此,这个应用的build.gradle文件就写完了,我们运行gradle build。我们发现在src平级目录下多了一个build文件夹,里面有classes、lib文件夹,classes里按照源文件的package名组织好了class文件,而整个项目打包好的war包就放在libs文件夹里,拷贝到Tomcat下就可以运行了。
那这个用构建好的Gradle工程怎么交给被人开发呢,毕竟一个项目是大家一起工作的,你不可能一个人完成所有的工作然后只提交war包。当你需要把自己的项目给其他人的时候,我们可以在gradle.build文件里加上这个:
task createWrapper(type: Wrapper) {
gradleVersion = '0.9'
}
意思是给gradle加了一个task,运行这个task:
gradle createWrapper
你就会发现生成了3个新的文件:
1.gradle文件夹
2.gradlew
3.gradlew.bat
这些个文件的意思就是,任何机器都可以运行这个build即使没有装gradle,linux用户直接运行gradlew,windows用户运行gradlew.bat,如果没有装就会根据gradle文件夹里面的配置下载特定版本。
我觉得这个是至关重要的,因为可以在一个:项目组内统一gradle版本。
好啦,这样大家就可以一起愉快的开发软件啦!
网友评论