使用kotlin构建一个spring boot应用

61 阅读4分钟

kotlin的语法优势

kotlin相对java的优势有很多,这里就不一一介绍。 只说两个我们常用的。

  • 非空类型,直接在类型定义时定义数据是否非空。可以减少90%以上的空指针异常,其它10%可能在你依赖的包里面。
  • ?. 可空值调用,这个方法可以减少90%以上的可空判断,代码量大大减少。 其它的就太多了,具体可以在其它地方搜一搜,或者有兴趣的可以留言讨论。

本文的主题是如何用kotlin构建一个spring boot应用。

spring对kotlin的支持可以说是亲儿子级别,spring boot文档里面的代码示例都是两种语言。而且spring官方特地提供了一篇用kotlin构建spring boot的官方指南。 使用kotlin构建spring boot应用 本文的要点大部分基于该示例,但用更简单的方式介绍。

如何从idea创建一个使用kotlin的spring boot项目

  1. 打开idea,点击 File -> New -> Project。
  2. 在 New Project 对话框中,选择 Spring Initializr。
  3. 在 Spring Initializr 对话框中,输入项目的 Group、Artifact、Name 等信息。 img_1.png
  4. 在 Dependencies 选项卡中,选择 Spring Boot DevTools、Spring Web、Spring data JPA 等依赖。 img_2.png
  5. 点击 Next 按钮,选择项目的存储位置。
  6. 点击 Finish 按钮,等待项目创建完成。

如何从spring initializr创建一个使用kotlin的spring boot项目

  1. 打开spring initializr,输入项目的 Group、Artifact、Name 等信息。
  2. 点击 Add Dependencies 按钮,选择 Spring Boot DevTools、Spring Web、Spring data JPA 等依赖。 img.png
  3. 点击 Generate 按钮,下载项目的压缩包。
  4. 解压压缩包,用idea/或者其它开发工具打开项目。

如何在现有项目中添加kotlin支持

使用前面的两个方法,都是新建项目,下面我们介绍一下如何在现有的java项目中添加kotlin支持。详情参考kotlin官方文件Adding Kotlin to a Java project – tutorial

  • 在使用maven构建的项目添加kotlin依赖
  1. 修改pom.xml添加在build块添加下列配置,以下配置可以使你的项目能正确识别和编译kotlin代码
<properties>
    <!--此处根据你需求选择,选择对应的kotlin版本。-->
    <!--如果是使用的spring boot脚手架搭建的项目,可以不写-->
    <!--如果使用其它方式搭建的spring bott项目,请根据你的版本使用对应的kotlin版本-->
    <kotlin.version>2.2.21</kotlin.version>
</properties>
<build>
    <pluginManagement><!-- Lock down plugin versions to avoid using Maven defaults (can be moved to a parent pom file) -->
        <plugins>
            <!-- No maven-compiler-plugin needed with Kotlin extensions -->
        </plugins>
    </pluginManagement>
    <plugins>
        <!-- Activate Kotlin Maven plugin for main and test sources -->
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <extensions>true</extensions>
            <executions>
                <execution>
                    <id>default-compile</id>
                    <phase>compile</phase>
                    <configuration>
                        <sourceDirs>
                            <sourceDir>src/main/kotlin</sourceDir>
                            <!-- Ensure Kotlin code can reference Java code -->
                            <sourceDir>src/main/java</sourceDir>
                        </sourceDirs>
                    </configuration>
                </execution>
                <execution>
                    <id>default-test-compile</id>
                    <phase>test-compile</phase>
                    <configuration>
                        <sourceDirs>
                            <sourceDir>src/test/kotlin</sourceDir>
                            <sourceDir>src/test/java</sourceDir>
                        </sourceDirs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  1. 在pom.xml中添加kotlin相关的库依赖,这些依赖库是kotlin运行时必须的
<dependencies>
    <!--下面两个模块是kotlin运行必备库,一个是kotlin标准库,一个是kotlin反射库-->
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-reflect</artifactId>
    </dependency>
    <!--下面是kotlin的jackson支持,使jackson能正确处理kotlin的一些特殊数据类型,比如 UInt,UByte等 -->
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-kotlin</artifactId>
    </dependency>
</dependencies>
  • 在使用gradle构建的项目中添加kotlin依赖
  1. 添加kotlin编译插件。
plugins {
    // kotlin编译插件,将kotlin代码编译为jvm字节码
    kotlin("jvm") version "2.2.21"
    // kotlin的spring插件,主要目的是让kotlin生成的类能正确的被spring容器识别并代理
    kotlin("plugin.spring") version "2.2.21"
    // 这个是让kotlin能正确处理jpa实体,如果没有使用jpa,可以不用添加该插件
    kotlin("plugin.jpa") version "2.2.21"
}
  1. 在依赖中添加相关的kotlin依赖
dependencies {
    // 下面两个模块是kotlin运行必备库,一个是kotlin标准库,一个是kotlin反射库
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib")
    // 下面是kotlin的jackson支持,使jackson能正确处理kotlin的一些特殊数据类型,比如 UInt,UByte等
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
}

经过上面的配置之后,就可以在项目中使用kotlin快乐的编码了。

使用kotlin构建项目

kotlin保持了和java一样的包结构。但支持在一个文件中声明多个类。但仍然推荐和java保持一样的包目录结构。这样我们就可以在不破坏现有结构的情况下,充分利用kotlin的语法优点。

  • 项目入口文件

这个文件和java版本的差别较大。

@SpringBootApplication
class AppApplication {

    @Bean
    fun dateTimeProvider(): DateTimeProvider {
        return DateTimeProvider { Optional.of(ZonedDateTime.now()) }
    }

}

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

项目入口文件和正常java的项目入口文件基本一致,需要注意的是kotlin的main方法不依赖任何类,所以main方法要写在AppApplication类的外部。

我们可以在AppApplication中添加更多的 @Bean. 比如上面的代码中就声明了一个类型为DateTimeProvider,名称为dateTimeProvider的bean

  • 一个controller的示例
@RestController
@RequestMapping("/users")
class UserController(
    private val userService: UserService
) {
    @GetMapping("{id}")
    fun getUser(
        @PathVariable("id") id: Long
    ): UserDto {
      return userService.findById(id)?:throw NoSuchElementException("用户不存在")
    }
}
  1. RestController/RequestMapping注解和java的没有任何区别。
  2. GetMapping/PathVariable等方法上的注解和java版本的没有任何区别。
  3. 当使用构造注入时,和java的构造函数注入没有本质的区别,但语法更简洁。
  4. 其它层的文件,基本和controller一致,就不再过多赘述。
  5. 接下来我们可以使用kt的语法优势,编写更简洁的代码了。