Kotlin语言和Gradle构建搭建SpringBoot工程

前言

最近想做一个小项目,遇到了后台开发问题,从Python、Go、Nodejs、Java、Kotlin中我对比选择了一下,最后还是决定使用自己最熟悉的Java开发,后来又想了一下,既然现在Android开发都是用Kotlin了,而且Kotlin语法这么灵活简介,为何不用Kotlin结合Gradle构建来搭建一个SpringBoot工程呢,整个过程也是本人在逐渐摸索,中间可能会遇到很多障碍和问题,但是没关系,俗话说开弓没有回头箭,因为我已经决定开始了。

搭建过程

第一步:首先去Intellij IDEA下载一个社区版,下载地址:https://www.jetbrains.com/idea/

第二步:去start spring网站建一个springboot工程。

创建springboot工程

第三步:导入工程。

第四步:在Preference中搜索gradle配置Gradle home和Gradle JVM:

配置Gradle路径和JDK路径

第五步:执行构建,整个过程比较慢,要耐心等待。

工程构建中

如果实在等不下去,建议你配置maven仓库的阿里云镜像,在根目录的gradle.build中添加如下:

1
2
3
4
repositories {
maven {url 'http://maven.aliyun.com/nexus/content/groups/public/'}
mavenCentral()
}

构建完成后整个工程目录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
lvip-server
├── HELP.md
├── build.gradle
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lvip-server.iml
├── settings.gradle
└── src
├── main
│   ├── kotlin
│   │   └── com
│   │   └── guohe
│   │   └── springboot
│   │   └── lvipserver
│   │   └── LvipServerApplication.kt
│   └── resources
│   ├── application.properties
│   ├── static
│   └── templates
└── test
└── kotlin
└── com
└── guohe
└── springboot
└── lvipserver
└── LvipServerApplicationTests.kt

我们会发现有一个LvipServerApplication.kt文件,这个是springboot的入口程序main,它会帮我们自动启动spring容器和Tomcat。

1
2
3
4
5
6
7
8
9
10
11
package com.guohe.springboot.lvipserver

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class LvipServerApplication

fun main(args: Array<String>) {
runApplication<LvipServerApplication>(*args)
}

其中@SpringBottApplication是SpringBoot的核心注解,主要作用是开启Spring自动配置。

运行helloword

我们新建一个controller目录并创建一个HelloController.kt测试文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.guohe.springboot.lvipserver.controller

import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class HelloCotroller {

@RequestMapping("/boot/hello")
@ResponseBody
fun hello(): String{
return "Hello SpringBoot";
}
}

打开LvipServiceApplication.kt,右键Run ‘com.guohe.springboot..’,可以在控制台看到如下输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.4.RELEASE)

2019-05-03 17:15:52.624 INFO 6847 --- [ main] c.g.s.l.LvipServerApplicationKt : Starting LvipServerApplicationKt on wangyingdeMacBook-Pro.local with PID 6847 (/Users/shuihan/Documents/github/lightVip/server/lvip-server/out/production/classes started by shuihan in /Users/shuihan/Documents/github/lightVip/server/lvip-server)
2019-05-03 17:15:52.627 INFO 6847 --- [ main] c.g.s.l.LvipServerApplicationKt : No active profile set, falling back to default profiles: default
2019-05-03 17:15:54.780 INFO 6847 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-05-03 17:15:54.818 INFO 6847 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-05-03 17:15:54.818 INFO 6847 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.17]
2019-05-03 17:15:55.022 INFO 6847 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-05-03 17:15:55.022 INFO 6847 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2293 ms
2019-05-03 17:15:55.255 INFO 6847 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-05-03 17:15:55.454 INFO 6847 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-05-03 17:15:55.457 INFO 6847 --- [ main] c.g.s.l.LvipServerApplicationKt : Started LvipServerApplicationKt in 3.416 seconds (JVM running for 3.957)
2019-05-03 17:16:02.120 INFO 6847 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-05-03 17:16:02.120 INFO 6847 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-05-03 17:16:02.126 INFO 6847 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms

接下来在浏览器中我们输入http://localhost:8080/boot/hello就可以看到浏览器显示Hello SpringBoot

我们看到虽然我们使用的是Spring MVC,但是没有xml配置,而且依赖的jar包也变简单了,只需要下面一个依赖就可以(其他依赖是关于kotlin和测试的):

1
implementation 'org.springframework.boot:spring-boot-starter-web'

但是我们打开工程下面的External Libraries会看到实际上依赖了很多jar包,上面这个spring-boot-starter-web称为父级依赖,这个依赖是一个特殊的依赖,它可以提供Spring MVC相关的依赖、会管理版本号,而且省去了很多配置。打开Gradle的Source Sets可以看到具体的依赖结构关系:

SpringBoot依赖关系

SpringBoot核心配置文件

SpringBoot的核心配置文件用于配置SpringBoot程序,有两种格式的配置文件,一种是.properties另一种是.yml的文件。

在工程的resources目录下有一个默认的application.properties文件,里面是空的,我们添加两个配置如下:

1
2
server.port=8080
server.context-path=/lvip

yml格式也可以写成yaml,我们在resources目录下新建一个application.yml文件,添加配置如下:

1
2
3
server:
port: 8080
context-path: /lvip

通常情况下我们在开发环境和生产环境的配置不一样,所以可以使用两套配置文件,然后在application.yml中配置选择那个配置文件, 例如我们新建了application-dev.ymlapplication-online.yml两个配置,选择dev环境配置:

1
2
3
spring:
profiles:
active: dev

或者使用application.properties配置如下(假设这次使用online环境):

1
spring.profiles.active=online

SpringBoot自定义配置

在SpringBoot的配置文件中还可以添加自定义配置,例如我添加如下两个blog自定义配置:

1
2
3
4
5
6
server:
port: 8080
context-path: /lvip
blog:
name: 水寒的博客
website: http://dp2px.com

然后定义一个名为BlogController.kt的Controller如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.guohe.springboot.lvipserver.controller

import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class BlogController {

@Value("\${blog.name}")
private val name: String? = null

@Value("\${blog.website}")
private val website: String? = null

@RequestMapping("/boot/blog")
@ResponseBody
fun blogInfo(): String{
return "$name : $website"
}
}

然后在浏览器中访问localhost:8080/lvip/boot/blog浏览器就会显示水寒的博客:http://dp2px.com

还有一种方式就是使用@ConfigurationProperties注解来读取自定义配置文件,定义如下:

1
2
3
4
5
6
7
8
9
package com.guohe.springboot.lvipserver.properties

import org.springframework.boot.context.properties.ConfigurationProperties

@ConfigurationProperties(prefix = "blog")
class BlogInfo {
var name: String? = null
var website: String? = null
}