Основное
Kora является облачно ориентированным серверным фреймворком и предлагает множество различных модулей для быстрого создания приложений такие как HTTP сервер, Kafka потребители, абстракция над базой данных в виде репозиториев, телеметрию всех модулей, отказоустойчивость и многое другое.
Kora предоставляет все необходимые для современной Java / Kotlin серверной разработки инструменты:
- Внедрение и инверсию зависимостей на этапе компиляции посредствам аннотаций
- Создание декларативно описанных с помощью аннотаций компонент во время компиляции
- Аспектно-ориентированное программирование посредствам аннотаций
- Пре-конфигурируемые модули интеграций
- Легкое и быстрое тестирование с помощью JUnit5
- Простая, понятная и подробная документация подкрепленная примерами сервисов
Для достижения высокопроизводительного и эффективного кода, Kora стоит на таких принципах:
- Создание исходного кода посредствам обработчиков аннотаций во время компиляции
- Отказ от использования Reflection API во время работы
- Отказ от динамических прокси
- Тонкие абстракции над модулями
- Бесплатные аспекты
- Использование только наиболее эффективных реализаций для модулей
- Поощрение и использование наиболее эффективных принципов разработки и естественных конструкций языка
- Отсутствие генерации байт-кода во время компиляции и во время работы
Обработчики аннотаций¶
Главный столп на котором строится фреймворк Kora это обработчики аннотаций.
Аннотация - это конструкция, связанная с элементами исходного кода Java, такими как классы, методы и переменные. Аннотации предоставляют программе информацию во время компиляции на основе которой программа может предпринять дальнейшие действия. Процессор аннотаций обрабатывает эти аннотации во время компиляции для обеспечения таких функций, как генерация кода, проверка ошибок и т.д.
Kora предоставляет в рамках одной зависимости все обработчики аннотаций, которые потребуются для работы со всеми модулями, процессоры не тянут за собой никакие лишние зависимости которые протекали бы во время компиляции или выполнения приложения.
Kotlin Symbol Processing (KSP) - это API, который можно использовать для разработки легких плагинов для компиляторов. KSP представляет собой упрощенный API для плагинов к компиляторам, который позволяет использовать возможности Kotlin при минимальной кривой обучения. По сравнению с kapt, процессоры аннотаций, использующие KSP, могут работать в два раза быстрее (но в разы медленее чем Java).
Другой способ представить KSP как препроцессорный фреймворк программ на языке Kotlin. Если рассматривать плагины на базе KSP как символьные процессоры, или просто процессоры, то поток данных при компиляции можно описать следующими шагами:
- Процессоры читают и анализируют исходные программы и ресурсы.
- Процессоры генерируют код или другие формы вывода.
- Компилятор Kotlin компилирует исходные программы вместе со сгенерированным кодом.
Такой подход позволяет использовать привычную всем парадигму программирования посредствам создания с помощью аннотаций HTTP-обработчиков, Kafka продюсеров, репозиториев баз данных и так далее, но дает огромный выйгрыш в производительности и прозрачности относительно известных всем JVM фреймворков.
Совместимость¶
Требуется версия не ниже JDK 17.
Конфигурация в build.gradle
:
Требуется версия не ниже JDK 17.
Рекомендуемая версия Kotlin 1.9+
, совместимость с версией 1.8+
и 2+
не гарантируется.
Рекомендуемая версия KSP 1.9+
соответсвующая версии Kotlin.
Конфигурация в build.gradle.kts
:
plugins {
kotlin("jvm") version ("1.9.10")
id("com.google.devtools.ksp") version ("1.9.10-1.0.13")
}
kotlin {
jvmToolchain { languageVersion.set(JavaLanguageVersion.of("17")) }
sourceSets.main { kotlin.srcDir("build/generated/ksp/main/kotlin") }
sourceSets.test { kotlin.srcDir("build/generated/ksp/test/kotlin") }
}
Система сборки¶
Поскольку основным столпом являются обработчики аннотаций, то подразумевается что вы будете использовать именно систему сборки Gradle,
так как она лучше других поддерживает обработчики аннотаций, инкрементальную сборку и является наиболее совершенной системой сборки в JVM экосистеме.
Требуется версия Gradle 7+
.
Для того чтобы не прописывать версии для каждой зависимости, предполагается использовать BOM
зависимость ru.tinkoff.kora:kora-parent
в которой требуется один раз указать версию для всех Kora зависимостей разом.
Kora поддерживает инкрементальную сборку из нескольких раундов на этапе обработки аннотаций, более подробное описание по работе с Gradle и Java можно почитать в их официальной документации.
Ниже будет представлена минимально необходимая конфигурация приложения build.gradle
:
plugins {
id "java"
id "application"
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
configurations {
koraBom
annotationProcessor.extendsFrom(koraBom)
compileOnly.extendsFrom(koraBom)
implementation.extendsFrom(koraBom)
api.extendsFrom(koraBom)
}
dependencies {
koraBom platform("ru.tinkoff.kora:kora-parent:1.1.15")
annotationProcessor "ru.tinkoff.kora:annotation-processors"
}
Также можно ознакомиться с ознакомительным примером с более подробным описанием.
Kora поддерживает инкрементальную сборку из нескольких раундов на этапе обработки аннотаций, более подробное описание по работе с Gradle и Kotlin можно почитать в их официальной документации, а также будет полезно ознакомиться с работой KSP в Gradle
Для Kotlin предполагается что будет использоваться Gradle Kotlin DSL, так что все примеры для Kotlin будут даваться именно в этом синтаксисе, если вы используете Groovy синтаксис, то используйте Java примеры.
Ниже будет представлена минимально необходимая конфигурация приложения build.gradle.kts
:
plugins {
id("application")
kotlin("jvm") version ("1.9.10")
id("com.google.devtools.ksp") version ("1.9.10-1.0.13")
}
kotlin {
jvmToolchain { languageVersion.set(JavaLanguageVersion.of("17")) }
sourceSets.main { kotlin.srcDir("build/generated/ksp/main/kotlin") }
sourceSets.test { kotlin.srcDir("build/generated/ksp/test/kotlin") }
}
val koraBom: Configuration by configurations.creating
configurations {
ksp.get().extendsFrom(koraBom)
compileOnly.get().extendsFrom(koraBom)
api.get().extendsFrom(koraBom)
implementation.get().extendsFrom(koraBom)
}
dependencies {
koraBom(platform("ru.tinkoff.kora:kora-parent:1.1.15"))
ksp("ru.tinkoff.kora:symbol-processors")
}
Также можно ознакомиться с ознакомительным примером с более подробным описанием.
Зависимости¶
Так как основным столпом на котором строится Kora являются обработчики аннотаций, то они являются обязательной зависимость, также не стоит забывать и о BOM зависимости:
build.gradle
:
build.gradle.kts
:
val koraBom: Configuration by configurations.creating
configurations {
ksp.get().extendsFrom(koraBom)
compileOnly.get().extendsFrom(koraBom)
api.get().extendsFrom(koraBom)
implementation.get().extendsFrom(koraBom)
}
dependencies {
koraBom(platform("ru.tinkoff.kora:kora-parent:1.1.15"))
ksp("ru.tinkoff.kora:symbol-processors")
}
Запуск¶
Запускать и работать с приложением через систему сборки, предполагается с помощью application плагина который предоставляет Gradle.
Требуется указать плагин в build.gradle
:
Можно указывать как системные переменные, так и переменные окружения при локальном запуске приложения в build.gradle
:
Запускать надо с помощью команды:
Настроить сборку артефакта можно таким способом в build.gradle
:
application {
applicationName = "application"
mainClassName = "ru.tinkoff.kora.java.Application"
applicationDefaultJvmArgs = ["-Dfile.encoding=UTF-8"]
}
distTar {
archiveFileName = "application.tar"
}
Собирать артефакт можно командой:
Пример настроенного приложения можно посмотреть тут
Требуется указать плагин в build.gradle
:
plugins {
id("application")
kotlin("jvm") version ("1.9.10")
id("com.google.devtools.ksp") version ("1.9.10-1.0.13")
}
Можно указывать как системные переменные, так и переменные окружения при локальном запуске приложения в build.gradle.kts
:
Запускать надо с помощью команды:
Настроить сборку артефакта можно таким способом:
application {
applicationName = "application"
mainClass.set("ru.tinkoff.kora.kotlin.ApplicationKt")
applicationDefaultJvmArgs = listOf("-Dfile.encoding=UTF-8")
}
tasks.distTar {
archiveFileName.set("application.tar")
}
Собирать артефакт можно командой:
Пример настроенного приложения можно посмотреть тут
Терминология¶
В данной секции описываются основные термины которые встречаются во всей документации и в рамках фреймворка Kora:
- Фабрика - под фабрикой подразумевается метод который, создает экземпляры компонент/классов/зависимостей.
- Модуль - под модулем понимается подключаемая зависимость, зачастую внешняя которая предоставляет какие-то фабричные методы и новый функционал в приложение.
- Компонент - под компонентом понимается класс в одном экземпляре (
Singleton
) который реализует какую то логику и является зависимостью в контейнере зависимостей. - Аспект - под аспектом подразумевается логика которая будет расширять стандартное поведение метода посредствам какой-либо аннотации до и/или после его выполнения.