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中添加如下:

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

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

 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。

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测试文件

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..‘,可以在控制台看到如下输出


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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和测试的):

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文件,里面是空的,我们添加两个配置如下:

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

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

server:
	port: 8080
	context-path: /lvip

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

spring:
  profiles:
    active: dev

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

spring.profiles.active=online

SpringBoot自定义配置

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

server:
  port: 8080
  context-path: /lvip
blog:
  name: 水寒的博客
  website: http://dp2px.com

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

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注解来读取自定义配置文件,定义如下:

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
}