SpringBoot 初体验,使用 Gradle 轻松配置最简环境
对 Gradle 脚本好奇很久了,这次终于抽时间简单看了一下,然后使用它配置了一个最简单的 SpringBoot 环境。
Gradle 简介
Gradle 和 JDK 的安装就略去不表了,使用包管理器或者去官网下载源码、二进制包都可以,只要保证版本足够新就好了(这里使用的是 Gradle 4.6 和 JDK 1.8 版本)。
使用 Gradle 脚本的第一步,你要知道 Groovy 语言,因为 Gradle 脚本是使用 Groovy 语言编写的。
我个人认为这是一个挺冷门的语言,至少我以前没见过它。这次也只是简单了解一下,并没有深入,不过我倒是觉得 Groovy 的语法和 Kotlin 有几分相似。
网上有很多介绍 Gradle 的基本概念的,这里也再重复一下。
首先,Gradle 使用 build.gradle
作为其配置文件。还有两个配置文件分别是 setting.gradle
和 gradle.properties
,不过我们这里的最简环境并没有用到。
所以,这里我们只需要编写 build.gradle
,在这个文件中,有一个 task 的概念,顾名思义,它就是 gradle 脚本中需要执行的一个任务。有如下代码:
task A {
doLast {
println "Hello A"
}
}
task B << {
println "Hello B"
}
task C(dependsOn: B) << {
println "Hello C"
}
使用如下方式执行:
➜ gradle -q A
Hello A
➜ gradle -q B
Hello B
➜ gradle -q C
Hello B
Hello C
先解释一个那个 -q
参数,就是 --quiet
的意思,和很多命令的 -q
参数一样,就是告诉 gradle 别 BB 了,除了错误以外的信息就不用显示了。
你应该也能猜到,使用 gradle A
就是执行 A 任务,gradle B
就是执行 B 任务了。
你可能发现 task A 使用了 doLast
,而 task B 使用了 <<
,其实他们的作用是一样的,后者是前者的简写而已。
那么,执行 task C 为什么除了输出 Hello C 之外,还会先输出 Hello B 呢?当然是这样了,因为 task C 依赖(dependsOn) task B 嘛。
你可以使用 gradle tasks
命令查看 gradle 还可以执行哪些 task。
上面只是随便简单介绍一下 build.gradle 的写法,更多请百度。
Gradle 插件
java 插件
Gradle 通过以下语法导入一个插件:
apply plugin: 'java'
build.gradle 的内容只有上面这一句,就是引入了一个名字叫 java 的插件,在引入这个插件后,运行 gradle tasks
,发现多了一些新任务,比如:
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.
Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.
可以看到,这个 java 插件赋予了我们编译 java 代码的能力,默认的,Java 代码路径应该保存在 src/main/java
路径下,当前的文件结构如下:
➜ tree
.
├── build.gradle
└── src
└── main
└── java
└── Main.java
3 directories, 2 files
Main.java 文件内容如下:
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
这是,我们只要执行 gradle build
命令,会看到以下提示:
➜ gradle build
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
此时就会自动生成一个 build 目录,如下:
➜ tree
.
├── build
│ ├── classes
│ │ └── java
│ │ └── main
│ │ └── Main.class
│ ├── libs
│ │ └── gradle-demo.jar
│ └── tmp
│ ├── compileJava
│ └── jar
│ └── MANIFEST.MF
├── build.gradle
└── src
└── main
└── java
└── Main.java
11 directories, 5 files
可以看到,gradle 已经成功编译出了一个 class 文件。如果你觉得 src/main/java
这个目录太长了,如何修改呢?可以把 build.gradle
修改成这样:
apply plugin: 'java'
sourceSets.main.java.srcDir 'src'
此时,就可以把 Main.java 移动到 src 目录下面了:
➜ tree
.
├── build.gradle
└── src
└── Main.java
1 directory, 2 files
application 插件
我们现在已经能够使用 gradle 来编译一份 Java 代码了,那么如果执行它呢?只需要引入另一个插件:
apply plugin: 'java'
sourceSets.main.java.srcDir 'src'
apply plugin: 'application'
mainClassName = 'Main'
并且我们配置了 mainClassName 的值为 'Main'
,顾名思义,就是主类的名称,如果类中定义了 package,则需要改为全类名,如:'net.conw.demo.Main'
。
此时执行 gradle tasks
可以看到,又多了一个新任务:
Application tasks
-----------------
run - Runs this project as a JVM application
试一下吧,执行 gradle run
:
➜ gradle run
> Task :run
Hello World
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
也可以执行 gradle -q run
让它安静一点儿:
➜ gradle -q run
Hello World
使用依赖
gradle 另外一个很重要的功能就是解决 jar 包依赖,正常如果我们使用 javac 编译的话,需要通过 -cp 参数指定 jar 包,非常麻烦,而在 gradle 中只需要简单的配置几行即可,比如我们想使用 com.google.code.gson
这个 jar 包来操作 JSON:
apply plugin: 'java'
sourceSets.main.java.srcDir 'src'
apply plugin: 'application'
mainClassName = 'Main'
repositories.jcenter()
dependencies.compile 'com.google.code.gson:gson:latest.integration'
我们又在 build.gradle 中配置了 repositories 和 dependencies,其中 repositories 就是下载 jar 包的仓库,也可以使用 mavenCentral(),而 dependencies.compile 则是配置编译期间依赖的 jar 包。
注意到我们把依赖写成了一个由 :
分隔的字符串的形式,其含义是 $group:$name:$version
,而 latest.integration
表示最新版本。
然后我们修改 Main.java 为以下内容:
import com.google.gson.Gson;
class Student {
public String number;
public String name;
public int age;
public Student(String number, String name, int age) {
this.number = number;
this.name = name;
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Gson gson = new Gson();
Student student = new Student("153889", "netcon", 22);
System.out.println(gson.toJson(student));
}
}
然后执行 gradle -q run
就能看到结果了,我们已经成功的把一个 student 对象转成 JSON 字符串了:
➜ gradle -q run
{"number":"153889","name":"netcon","age":22}
使用 SpringBoot
看到这里,你应该已经能想到,如果我们想通过 gradle 使用 SpringBoot 的话,应该也是通过使用插件的方式,这个插件就叫 org.springframework.boot
。
不过你如果还是通过之前的方式引入插件的话,会得到一个错误,比如这样:
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
会提示 Plugin with id 'org.springframework.boot' not found.
,这时候你需要再编写一段 buildscript
,可以在先里面声明 gradle 脚本的依赖。
然后我们还需要声明 SpringBoot 项目代码中用到的 jar 包,最终 build.gradle
配置如下:
buildscript {
repositories.jcenter()
dependencies.classpath 'org.springframework.boot:spring-boot-gradle-plugin:latest.integration'
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
sourceSets.main.java.srcDir 'src'
repositories.jcenter()
dependencies.compile 'org.springframework.boot:spring-boot-starter-web:latest.integration'
然后修改 Main.java 为如下内容:
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
@Controller
@EnableAutoConfiguration
class HomeController {
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello SpringBoot!";
}
}
public class Main {
public static void main(String[] args) throws Exception {
SpringApplication.run(HomeController.class, args);
}
}
在导入 org.springframework.boot
插件后,gradle 就多了一个 bootRun 的任务,执行它试试:
➜ gradle bootRun
......
......
......
2018-04-17 15:42:49.142 INFO 19496 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-04-17 15:42:49.142 INFO 19496 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-04-17 15:42:49.172 INFO 19496 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 30 ms
<=========----> 75% EXECUTING [11s]
> :bootRun
不用等进度条走到 100% (-.-),走到 75% 就好了,然后打开浏览器访问 http://localhost:8080
试试,是不是已经可以成功访问了?
(如果上面这一步出现错误,请检查是不是本地 8080 端口已经被占用)
看到这里,如果再让你使用 gradle 配置一个最简单 Kotlin SpringBoot 环境,相信对你来说也是小菜一碟了~
(完)
null