搭建SpringBoot2.x Kotlin开发环境

Kotlin简介:Kotlin是一个基于JVM的静态类型编程语言,由JetBrains设计开发并开源。Kotlin能够与Java进行完全的交互,可以在同一个项目中同时使用Java和Kotlin。并且支持多种平台,包括移动端、服务端以及浏览器端,Kotlin已正式成为Android官方支持开发语言。
Spring Framework 5.0版本中已经正式支持Kotlin语言,SpringBoot从SpringBoot2开始也正式支持Kotlin。

最近刚开始学习Kotlin,也踩了一些坑,顺便总结一下基于kotlin开发的SpringBoot2.x环境搭建。

一、环境准备

  • 开发工具:idea 2019
  • 项目构建工具:maven 3.6.1
  • JDK:1.8.0_181
  • SpringBoot:2.2.2.RELEASE
  • Kotlin:1.3.61

二、构建项目

这里直接通过maven构建一个java项目,然后对pom文件进行修改,添加kotlin相关依赖和插件,完整的pom文件如下:


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>com.rtxtitanvgroupId>
    <artifactId>springboot-kotlinartifactId>
    <version>1.0.0version>
    <packaging>jarpackaging>

    <name>springboot-kotlinname>
    <description>SpringBoot2.x kotlin 开发环境description>

    <parent>
        
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.2.RELEASEversion>
        <relativePath/> 
    parent>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        
        <kotlin.compiler.incremental>truekotlin.compiler.incremental>
        <java.version>1.8java.version>
        <kotlin.version>1.3.61kotlin.version>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.modulegroupId>
            <artifactId>jackson-module-kotlinartifactId>
        dependency>
        
        <dependency>
            <groupId>org.jetbrains.kotlingroupId>
            <artifactId>kotlin-reflectartifactId>
        dependency>
        
        <dependency>
            <groupId>org.jetbrains.kotlingroupId>
            <artifactId>kotlin-stdlib-jdk8artifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <build>
        
        <sourceDirectory>${project.basedir}/src/main/kotlinsourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlintestSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
            
            <plugin>
                <groupId>org.jetbrains.kotlingroupId>
                <artifactId>kotlin-maven-pluginartifactId>
                <version>${kotlin.version}version>
                <configuration>
                    <args>
                        
                        <arg>-Xjsr305=strictarg>
                    args>
                    <compilerPlugins>
                        
                        <plugin>springplugin>
                        
                        <plugin>no-argplugin>
                    compilerPlugins>
                    <pluginOptions>
                        
                        <option>no-arg:annotation=com.rtxtitanv.annotation.KtNoArgsConstructoroption>
                    pluginOptions>
                configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlingroupId>
                        <artifactId>kotlin-maven-allopenartifactId>
                        <version>${kotlin.version}version>
                    dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlingroupId>
                        <artifactId>kotlin-maven-noargartifactId>
                        <version>${kotlin.version}version>
                    dependency>
                dependencies>
                <executions>
                    <execution>
                        <id>compileid>
                        <goals> <goal>compilegoal> goals>
                    execution>
                    <execution>
                        <id>test-compileid>
                        <goals> <goal>test-compilegoal> goals>
                    execution>
                executions>
            plugin>
        plugins>
    build>

project>

项目结构如下:
搭建SpringBoot2.x Kotlin开发环境_第1张图片
编写主启动类,一个最简单的基于Kotlin的SpringBoot项目就构建完成了。

package com.rtxtitanv

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

/**
 * @name com.rtxtitanv.KotlinApplication
 * @description 主启动类
 * @author rtxtitanv
 * @date 2020/1/16 14:48
 * @version v1.0.0
 */
@SpringBootApplication
class KotlinApplication

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

三、使用测试

进行一些简单的测试,看能否正常使用Kotlin开发SpringBoot应用。

1.数据模型类

这里使用Data数据类,一般情况下编译器会自动生成equals()、 hashCode()、toString()等函数,至于getter和setter,没有显示定义Kotlin会默认自动生成。

package com.rtxtitanv.model

import com.rtxtitanv.annotation.KtNoArgsConstructor

/**
 * @name com.rtxtitanv.model.User
 * @description 用户实体类
 * @author rtxtitanv
 * @date 2020/1/16 16:07
 * @version v1.0.0
 */
@KtNoArgsConstructor
data class User(var id: Long? = null,//?表示声明为Nullable变量
                var userName: String? = null,
                var passWord: String? = null,
                var nickName: String? = null,
                var age: Int? = null,
                var tel: String? = null,
                var addr: String? = null)

自定义如下注解主要用于Kotlin的no-arg插件,指定该注解应用于no-arg插件,即注解有该注解的类。no-arg插件会为其自动添加无参构造函数,不过该无参构造函数只能通过反射调用,如果User类主构造函数中初始化了属性值,则可以通过User()调用无参构造函数,省略no-args插件也可以,也可以反射调用无参构造函数。

package com.rtxtitanv.annotation

/**
 * @name com.rtxtitanv.annotation.KtNoArgsConstructor
 * @description kotlin自定义无参构造器注解
 * @author rtxtitanv
 * @date 2020/1/16 16:57
 * @version v1.0.0
 */
annotation class KtNoArgsConstructor

2.单元测试

package com.rtxtitanv

import com.rtxtitanv.model.User
import org.junit.Test
import org.junit.runner.RunWith
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringRunner

/**
 * @name com.rtxtitanv.KotlinTest
 * @description 单元测试类
 * @author rtxtitanv
 * @date 2020/1/16 15:33
 * @version v1.0.0
 */
@RunWith(SpringRunner::class)
@SpringBootTest(classes = [KotlinApplication::class])
class KotlinTest {

    private val logger: Logger = LoggerFactory.getLogger(KotlinTest::class.java)

    @Test
    fun kotlinTest() {
        //通过反射调用自动生成的无参构造函数
        val user1 = User::class.java.newInstance()
        //在User类主构造函数中初始化了属性值,则可以通过User()调用无参构造函数,省略no-args插件也可以,也可以反射调用
        //如果没有在主构造函数中初始化属性值,则不能通过User()显式调用无参构造函数,必须要加上应用no-args插件的注解
        //且通过反射调用
        val user2 = User()
        logger.info("user1: " + user1.toString())
        logger.info("user2: " + user2.toString())
    }
}

控制台打印的日志说明自动生成了无参构造函数。

2020-01-17 21:39:21.172  INFO 15164 --- [           main] com.rtxtitanv.KotlinTest                 : user1: User(id=null, userName=null, passWord=null, nickName=null, age=null, tel=null, addr=null)
2020-01-17 21:39:21.172  INFO 15164 --- [           main] com.rtxtitanv.KotlinTest                 : user2: User(id=null, userName=null, passWord=null, nickName=null, age=null, tel=null, addr=null)

3.service层

这里省去了数据层,数据为手动模拟的,主要用于控制层返回数据测试。

package com.rtxtitanv.service

import com.rtxtitanv.model.User

/**
 * @name com.rtxtitanv.service.KotlinService
 * @description KotlinService接口
 * @author rtxtitanv
 * @date 2020/1/16 17:06
 * @version v1.0.0
 */
interface KotlinService {

    /**
     * 根据年龄查询用户
     */
    fun findUserByAge(age: Int): List<User>
}
package com.rtxtitanv.service.impl

import com.rtxtitanv.model.User
import com.rtxtitanv.service.KotlinService
import org.springframework.stereotype.Service

/**
 * @name com.rtxtitanv.service.impl.KotlinServiceImpl
 * @description KotlinService实现类
 * @author rtxtitanv
 * @date 2020/1/16 17:07
 * @version v1.0.0
 */
@Service
class KotlinServiceImpl : KotlinService {
    /**
     * 模拟根据年龄查询用户,只是测试,返回写死的user数据
     */
    override fun findUserByAge(age: Int): List<User> {
        val user1 = User(1L, "aaa",
                "123456", "abc",
                age, "198658632", "北京")
        val user2 = User(2L, "bbb",
                "111222", "cba",
                age, "15963247851", "上海")
        val userList = ArrayList<User>()
        userList.add(user1)
        userList.add(user2)
        return userList
    }
}

4.controller层

package com.rtxtitanv.controller

import com.rtxtitanv.model.User
import com.rtxtitanv.service.KotlinService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

/**
 * @name com.rtxtitanv.controller.KotlinController
 * @description KotlinController
 * @author rtxtitanv
 * @date 2020/1/16 14:59
 * @version v1.0.0
 */
@RequestMapping("/kotlin")
@RestController
class KotlinController(private val kotlinService: KotlinService) {
    /**
     * springboot2.x kotlin开发环境测试
     */
    @GetMapping("/test")
    fun helloKotlin(): String {
        return "hello kotlin!"
    }

    /**
     * 根据年龄查询用户
     */
    @GetMapping("/user/{age}")
    fun findUser(@PathVariable age: Int): List<User> {
        return kotlinService.findUserByAge(age)
    }
}

访问localhost:8080/kotlin/test
搭建SpringBoot2.x Kotlin开发环境_第2张图片
访问localhost:8080/kotlin/user/25
搭建SpringBoot2.x Kotlin开发环境_第3张图片
能正常返回json数据,说明一个基于Kotlin的简单SpringBoot2.x开发环境就搭建完成了。可以看出Kotlin非常适合开发服务器端应用程序,可以编写出简明且表现力强的代码,同时保持与现有基于Java的技术栈的完全兼容性,所以Kotlin还是有必要学习和掌握的。

代码示例

  • Github:https://github.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-kotlin
  • Gitee:https://gitee.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-kotlin

你可能感兴趣的:(SpringBoot)