Files
2026-10-09 23:03:53 +08:00

5.8 KiB
Raw Permalink Blame History

尝试 Kotlin Springboot

总体上来讲,Kotlin 与 Java 相比是有好有坏的,优点是写起来更简洁,缺点是写起来更简洁。

Springboot(Spring) 是目前 JVM 平台功能最强大、扩展性最好、健壮性最好的后端框架。

创建一个 Springboot 项目

这很简单,在 IDEA 中就可以创建,记得选 Kotlin 和 Gradle kts。

自带插件的话根据你的需要来选就好,如果你只是想利用 Springboot 来做一个命令行小程序也是可以的。

插件与依赖

build.gradle.kts 插件配置

新建项目后,你的 plugins 里面应该有这几项:

plugins {
    // 可以不用定义变量,但要保证版本一致
    val kotlinVersion = "2.0.0"
    kotlin("jvm") version kotlinVersion

    // Spring 专用的 Kotlin 编译器插件
    kotlin("plugin.spring") version kotlinVersion

    id("org.springframework.boot") version "3.3.0"
    id("io.spring.dependency-management") version "1.1.5"

    // 如果你用 JPA,建议加上这个,自动给数据实体类生成无参构造函数
    // kotlin("plugin.jpa") version kotlinVersion
}

依赖配置

在 dependencies 里,除了常规的 spring-boot-starter-web,还需要带上 Kotlin 的反射库:

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")

    // Kotlin 反射库,Spring 容器扫描注入时需要用到
    implementation("org.jetbrains.kotlin:kotlin-reflect")

    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

在 Java 下通常默认用 Jackson 来处理 JSON;而在 Kotlin 下,通常更推荐配合 Kotlin 原生的序列化方案。

项目文件的文件夹分类

在 Springboot 里面,基本就是大家非常熟悉的经典 MVC 分层结构。在 Kotlin 里面一般也是这么分:

  • src/main/kotlin/com/example/demo/
    • DemoApplication.kt:启动类,里面有 @SpringBootApplication 和 main 函数
    • controller/:接收前端请求的 Controller,写路由接口的地方(例如 UserController.kt)
    • service/:业务接口与实现类(例如 UserService.kt)
    • repository/ 或 dao/:数据库访问层(比如 Spring Data JPA 的接口或 MyBatis 的 Mapper),如果是 Mapper 的话有时会直接写作 Mapper。
    • entity/:数据库表对应的实体类
    • dto/:数据传输对象(前端传进来的 Request,或者返回给前端的 Response),有时会选择放在 entity 里面
    • config/:全局配置类(跨域配置、Spring Security 配置等)
    • exception/:全局异常拦截类(@RestControllerAdvice)
  • src/main/resources/
    • application.yml:全局配置文件(推荐用 yml,结构比 properties 清晰很多)

基本的编写思路

Kotlin 写 Springboot 和 Java 最大的区别,就是 Kotlin 本身的特性减少了大量代码。

构造器注入

在 Java 常使用 @Autowired,但在 Kotlin 里面,直接用主构造函数用写变量定义即可:

@Service
class UserService(
    private val userRepository: UserRepository // 类对象被创建时自动注入对象
) {
    fun findUser(id: Long): UserDto {
        val user = userRepository.findById(id).orElseThrow()
        return UserDto(user.id, user.name)
    }
}

用 data class 写 DTO 和数据载体

Java 会使用 Lombok 生成标准 Java Bean 类,Kotlin 的 data class 会自动生成 getter/setter、equals、hashCode、copy:

data class CreateUserRequest(
    val username: String,
    val email: String? = null // 问号表示可以为 null,对应选填字段
)

data class UserDto(
    val id: Long,
    val username: String
)

Controller

Controller 写法和常规 Springboot 一模一样,但由于 Kotlin 支持单行表达式,写起来格外干净:

@RestController
@RequestMapping("/api/users")
class UserController(
    private val userService: UserService
) {
    @GetMapping("/{id}")
    fun getUser(
        @PathVariable id: Long
    ): UserDto {
        return userService.findUser(id)
    }

    @PostMapping
    fun createUser(
        @RequestBody request: CreateUserRequest
    ): UserDto {
        return userService.createUser(request)
    }
}

全局异常处理

用 @RestControllerAdvice 兜底,不用在 Controller 里写 try-catch:

@RestControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(NoSuchElementException::class)
    fun handleNotFound(e: NoSuchElementException): ResponseEntity<String> {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.message)
    }
}

配置文件的写法

Springboot 支持 .properties 和 .yml,强烈推荐使用 application.yml。

在 src/main/resources/application.yml 里一般写:

server:
  port: 8080 # 端口

spring:
  application:
    name: my-kotlin-app
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: rootpassword

# 自定义配置
my-config:
  token-secret: "abcdefg123456"

在 Kotlin 代码中读取配置

有两种常见方式:

@Value

适合只读取一两个简单变量:

@Component
class MyComponent(
    @Value("$${my-config.token-secret}") private val tokenSecret: String
)

@ConfigurationProperties 与 data class

把整块配置映射成一个不可变的数据类,方便快捷:

@ConfigurationProperties(prefix = "my-config")
data class MyConfigProperties(
    val tokenSecret: String
)

只要在启动类上加上 @ConfigurationPropertiesScan,就可以直接把它像普通 Service 一样注入到任何地方使用了。

接下来可以看

目录

下一篇:Kotlin Ktor

更进一步:成为 Kotlin 超人

进入 KMP