Spring Boot + Kotlin для Kotlin: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс
Spring Boot + Kotlin: полное руководство с примерами

Spring Boot + Kotlin для Kotlin: полное руководство с примерами

1. Что это и зачем нужна

Spring Boot + Kotlin — это комбинация фреймворка Spring Boot и языка программирования Kotlin, которая позволяет создавать современные, надёжные и производительные серверные приложения с минимальным шаблонным кодом. Spring Boot — это популярный Java-фреймворк для создания микросервисов и веб-приложений, а Kotlin — современный статически типизированный язык, полностью совместимый с Java. Вместе они образуют мощный стек для разработки backend-систем.

Зачем это нужно? Во-первых, Kotlin значительно сокращает объём кода по сравнению с Java благодаря таким фичам, как data class, nullable types, extension functions и coroutines. Во-вторых, Spring Boot предоставляет готовые решения для типовых задач: конфигурация через аннотации, встроенный сервер (Tomcat, Netty), работа с базами данных (Spring Data JPA, R2DBC), безопасность (Spring Security) и создание REST API. В-третьих, Kotlin идеально вписывается в экосистему Spring: все аннотации и API работают «из коробки», а компилятор Kotlin генерирует байт-код, совместимый с JVM.

Эта библиотека (точнее, набор библиотек и инструментов) используется для построения высоконагруженных веб-сервисов, микросервисной архитектуры, обработки событий, работы с сообщениями (Kafka, RabbitMQ) и многого другого. Благодаря реактивному стеку Spring WebFlux и корутинам Kotlin, можно создавать неблокирующие приложения с отличной производительностью.

Примечание: Spring Boot + Kotlin — это не отдельная библиотека, а экосистема. Основные артефакты: spring-boot-starter-web, spring-boot-starter-data-jpa, spring-boot-starter-webflux и другие. Установка происходит через систему сборки Gradle или Maven.

2. Установка

Поскольку Spring Boot — это Java/Kotlin фреймворк, установка производится через систему сборки Gradle (рекомендуется) или Maven. Ниже приведены точные команды для инициализации проекта с помощью Gradle (Kotlin DSL).

2.1. Инициализация проекта через Gradle (Kotlin DSL)

Создайте файл build.gradle.kts в корне проекта:

plugins {
    kotlin("jvm") version "1.9.22"
    kotlin("plugin.spring") version "1.9.22"
    kotlin("plugin.jpa") version "1.9.22"
    id("org.springframework.boot") version "3.2.2"
    id("io.spring.dependency-management") version "1.1.4"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-validation")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    runtimeOnly("com.h2database:h2")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

kotlin {
    jvmToolchain(17)
}

После создания файла выполните команду для загрузки зависимостей:

./gradlew build

Если вы используете Maven, создайте pom.xml с соответствующими зависимостями. Однако для Kotlin-проектов Gradle является стандартом де-факто.

Совет: Для быстрого старта используйте Spring Initializr — выберите Kotlin, Gradle, добавьте нужные стартеры и скачайте готовый проект.

3. Быстрый старт — минимальный рабочий пример

Создадим простое REST приложение, которое возвращает «Hello, Kotlin!».

3.1. Структура проекта

src/
 └── main/
     └── kotlin/
         └── com/
             └── example/
                 └── demo/
                     ├── DemoApplication.kt
                     └── HelloController.kt

3.2. Главный класс приложения

package com.example.demo

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

@SpringBootApplication
class DemoApplication

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

3.3. Контроллер

package com.example.demo

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class HelloController {

    @GetMapping("/hello")
    fun sayHello(): String {
        return "Hello, Kotlin!"
    }
}

3.4. Запуск

Выполните команду:

./gradlew bootRun

Откройте браузер по адресу http://localhost:8080/hello. Вы увидите: Hello, Kotlin!

Примечание: В Kotlin не нужно писать @JvmStatic для main-функции — Spring Boot автоматически распознаёт runApplication<DemoApplication>().

4. Основные методы/функции/классы

Рассмотрим ключевые компоненты Spring Boot + Kotlin, которые вы будете использовать ежедневно. Для каждого приведена сигнатура, описание и рабочий пример.

4.1. @SpringBootApplication

Сигнатура: @Target(AnnotationTarget.CLASS) annotation class SpringBootApplication

Что делает: Помечает главный класс конфигурации Spring Boot. Объединяет @Configuration, @EnableAutoConfiguration и @ComponentScan.

@SpringBootApplication
class Application

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

4.2. @RestController

Сигнатура: @Target(AnnotationTarget.CLASS) annotation class RestController

Что делает: Указывает, что класс является контроллером REST, где каждый метод возвращает данные (JSON/XML) напрямую, без представления.

@RestController
class UserController {

    @GetMapping("/user")
    fun getUser(): Map<String, Any> {
        return mapOf("name" to "Alice", "age" to 30)
    }
}

4.3. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping

Сигнатура: @Target(AnnotationTarget.FUNCTION) annotation class GetMapping(val value: String = "", ...)

Что делает: Сопоставляет HTTP-методы с методами контроллера. @GetMapping для GET, @PostMapping для POST и т.д.

@RestController
class ItemController {

    @GetMapping("/items")
    fun getAllItems(): List<String> = listOf("item1", "item2")

    @PostMapping("/items")
    fun createItem(@RequestBody item: String): String {
        return "Created: $item"
    }
}

4.4. @RequestBody

Сигнатура: @Target(AnnotationTarget.VALUE_PARAMETER) annotation class RequestBody

Что делает: Связывает тело HTTP-запроса с параметром метода. Автоматически десериализует JSON в объект Kotlin.

data class Product(val id: Long, val name: String, val price: Double)

@PostMapping("/products")
fun createProduct(@RequestBody product: Product): Product {
    // сохраняем product в БД
    return product
}

4.5. @PathVariable

Сигнатура: @Target(AnnotationTarget.VALUE_PARAMETER) annotation class PathVariable(val value: String = "")

Что делает: Извлекает значение из шаблона URI.

@GetMapping("/users/{id}")
fun getUserById(@PathVariable id: Long): String {
    return "User with id: $id"
}

4.6. @Service

Сигнатура: @Target(AnnotationTarget.CLASS) annotation class Service

Что делает: Помечает класс как сервис (бизнес-логика). Spring автоматически создаёт бин этого класса.

@Service
class UserService(private val userRepository: UserRepository) {

    fun findUser(id: Long): User? {
        return userRepository.findById(id).orElse(null)
    }
}

4.7. @Repository и JpaRepository

Сигнатура: interface JpaRepository<T, ID> : PagingAndSortingRepository<T, ID>

Что делает: @Repository помечает DAO-класс. JpaRepository предоставляет готовые CRUD-методы (save, findById, findAll, delete).

@Repository
interface UserRepository : JpaRepository<User, Long> {
    fun findByName(name: String): List<User>
}

// Использование в сервисе:
@Service
class UserService(private val userRepository: UserRepository) {
    fun saveUser(user: User): User = userRepository.save(user)
}

4.8. @ConfigurationProperties

Сигнатура: @Target(AnnotationTarget.CLASS) annotation class ConfigurationProperties(val prefix: String = "")

Что делает: Связывает свойства из application.properties или application.yml с классом Kotlin.

@ConfigurationProperties(prefix = "app")
@ConstructorBinding
data class AppProperties(
    val name: String,
    val version: String,
    val features: List<String>
)

// application.yml:
// app:
//   name: MyApp
//   version: 1.0
//   features:
//     - auth
//     - logging

4.9. @ExceptionHandler

Сигнатура: @Target(AnnotationTarget.FUNCTION) annotation class ExceptionHandler(vararg val value: KClass<out Throwable>)

Что делает: Обрабатывает исключения, выбрасываемые в контроллере. Позволяет вернуть кастомный HTTP-ответ.

@RestControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(NoSuchElementException::class)
    fun handleNotFound(ex: NoSuchElementException): ResponseEntity<Map<String, String>> {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body(mapOf("error" to ex.message ?: "Resource not found"))
    }
}

4.10. @Transactional

Сигнатура: @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class Transactional

Что делает: Управляет транзакциями базы данных. Метод выполняется в рамках

Рекомендаций