使用Groovy编写Spring Boot应用
考虑到我正在使用Gradle,我本打算尝试用Groovy来写应用程序的,但昨天被 IDEA 15 的建议打败了,我写成了Kotlin,但今天决定还是试试用Groovy来写。
这个 build.gradle 是不是看起来很简单呢?
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.0.RELEASE")
classpath("org.springframework:springloaded:1.2.4.RELEASE")
}
}
apply plugin: 'groovy'
apply plugin: 'spring-boot'
apply plugin: 'idea'
idea {
module {
inheritOutputDirs = false
outputDir = file("$buildDir/classes/main/")
}
}
sourceSets {
main.groovy.srcDirs += 'src/main/groovy'
}
repositories {
mavenCentral()
}
dependencies {
compile("org.codehaus.groovy:groovy-all")
compile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8")
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
在使用./gradlew idea进行设置之后,我们将使用Groovy来编写代码。
Groovy与Kotlin一样,没有类型,因此我们使用java.util.Optional。由于Spring Boot的JSON渲染使用的Jackson默认不会很好地处理Optional,所以我们需要将jackson-datatype-jdk8的Jdk8Module添加到dependencies并进行配置。
package friendlist
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
@Configuration
@EnableAutoConfiguration
@ComponentScan
class Application {
@Configuration
static class JacksonModuleConfiguration {
@Bean
Jdk8Module javaOptionalModule() {
new Jdk8Module()
}
}
static void main(String[] args) {
SpringApplication.run(Application.class, args)
}
}
Groovy真是个方便易用的语言,可以直接在Java代码中进行修改。不过,有时候我会想写上”static def main”之类的代码,可惜它是不能写的呢。
你可以将def视为Object的别名,一瞬间就会理解。
下面我们将写下与Kotlin示例中的model和Controller相似的代码。
package friendlist.model
class Friend {
Integer id
Optional<String> name
private static ALL_FRIENDS = Arrays.asList(
new Friend(id: 1, name: Optional.of("Alice")),
new Friend(id: 2, name: Optional.of("Bob")),
new Friend(id: 3, name: Optional.of("Chris")),
new Friend(id: 4, name: Optional.of("Denny")),
)
static List<Friend> findAll() {
ALL_FRIENDS
}
static Optional<Friend> findById(Integer id) {
Optional.ofNullable(ALL_FRIENDS.find { f -> f.id == id })
}
}
class FriendResponse {
Optional<Friend> friend
}
class FriendsResponse {
List<Friend> friends
}
Groovy这种无需写return就可以的特点真是太棒了。
package friendlist.web
import friendlist.model.Friend
import friendlist.model.FriendResponse
import friendlist.model.FriendsResponse
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class HomeController {
@RequestMapping("/")
// def でも動く
def home() {
showAll()
}
@RequestMapping("/friends")
FriendsResponse showAll() {
new FriendsResponse(friends: Friend.findAll())
}
@RequestMapping("/friends/{id}")
FriendResponse show(@PathVariable Integer id) {
new FriendResponse(friend: Friend.findById(id))
}
}
使用./gradlew bootRun命令启动它。Spring Loaded已启用,如果更改了Groovy代码,则除了重新加载Spring配置和静态内容的细微情况外,将进行热重载。
$ curl -v localhost:8080/
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 25 Nov 2015 12:43:38 GMT
<
* Connection #0 to host localhost left intact
{"friends":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":3,"name":"Chris"},{"id":4,"name":"Denny"}]}
$ curl -v localhost:8080/friends/1
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /friends/1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 25 Nov 2015 12:43:44 GMT
<
* Connection #0 to host localhost left intact
{"friend":{"id":1,"name":"Alice"}}
$ curl -v localhost:8080/friends/10
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /friends/10 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 25 Nov 2015 12:43:46 GMT
<
* Connection #0 to host localhost left intact
{"friend":null}
这也很顺利。Gradle + Spring Boot 真是方便又好用啊。