Эта лекция была пересказом доклада Вадима Лузика “Жизнь без Spring на Kotlin”. Презентация доступна здесь: https://cdn.tbank.ru/static/meetups/talks/24ef1ef4-c17a-4734-a54d-907828dcfb7d.pdf
Spring - это мощный фреймворк, но именно его универсальность делает его громоздким. Он тянет за собой множество конфигураций и зависимостей. Даже если используется лишь малая часть функциональности, всё равно нужно понимать, как работает остальное - просто потому, что это часть экосистемы. Это повышает порог входа и замедляет разработку на начальных этапах.
Кроме того, из-за своей масштабности Spring-приложения зачастую имеют высокие накладные расходы: потребляют больше памяти, требуют больше CPU, что особенно критично в условиях ограниченных ресурсов
Быстродействие таких приложений тоже страдает. В сравнении с легковесными фреймворками, Spring может запускаться в 3-5 раз медленнее, а потребление ресурсов под нагрузкой выше.
Кривая обучения достаточно крутая. Новичкам без опыта работы со Spring нужно время, чтобы освоить такие ключевые концепции, как IoC-контейнер, бины, автоконфигурация, AOP и т.д. Даже простой REST-контроллер может оказаться непрозрачным из-за аннотаций и скрытой магии.
Есть ли альтернативы? Да, и их немало. Вот список актуальных альтернатив Spring, включая как Java-, так и Kotlin-фреймворки:
Spring Boot остаётся самым популярным, но эта популярность - не всегда индикатор технологического превосходства. Альтернативы - в том числе Ktor - предлагают иной подход: меньше магии, больше контроля и лёгкость в старте
Ktor - это фреймворк от JetBrains, написанный на Kotlin. Это даёт ему несколько серьёзных преимуществ:
Если важна скорость разработки и контроль над архитектурой, Ktor - достойный выбор.
Как же создать приложение на Ktor?
Для DI на Kotlin есть несколько вариантов:
Выбираем Koin, потому что:
@Single
, @Factory
, @Inject
)Можно использовать application.yml
для хранения настроек. Ktor позволяет удобно вытаскивать параметры конфигурации из этого файла с помощью конфигурационных классов. Это особенно удобно для перехода со Spring
Теперь можно добавить зависимости для MongoDB Kotlin Driver. Используем асинхронный API. Строим слой репозитория вручную, без Spring Data, что требует немного больше усилий, но даёт больше гибкости и понимания процессов
Чтобы с нашим приложением можно было общаться, интегрируем приложение с Kafka. Ktor не имеет встроенной поддержки Kafka, поэтому всё конфигурируется вручную через стандартные Kafka-клиенты
Для обращения к внешним API используем Ktor HttpClient. Он тоже построен на корутинах, легко конфигурируется и интегрируется
Теперь можно сравнить это приложение на Ktor с аналогичным на Spring:
Метрика | Ktor | Spring Boot |
---|---|---|
Время старта | 0.6 сек | 2.49 сек |
Размер .jar |
36.5 МБ | 49.9 МБ |
Нагрузочные тесты с использованием JMeter | Меньше потребление памяти | Выше потребление памяти |
Это важно: разница в скорости и ресурсоемкости особенно заметна под высокой нагрузкой. При лёгкой нагрузке всё примерно одинаково. Но когда начинается интенсивная работа - Ktor показывает себя эффективнее
Выводы: