Как упростить работу с модульностью

Как упростить работу с модульностью

Итак, мы решили стартовать наш проект с модульной архитектуры. Мы используем Spring Boot для разработки приложения на языке Java/Kotlin. Какие инструменты нам позволят упростить работу по реализации модульного монолита? Один из таких инструментов - Spring Modulith.

Что такое Spring Modulith

Spring Modulith - это относительно новый проект в экосистеме Spring, разработанный для упрощения создания хорошо структурированных, модульных монолитов на базе Spring Boot. Он не диктует жесткие правила, но предоставляет набор инструментов, которые помогают поддерживать модульную архитектуру, верифицировать границы модулей и облегчать дальнейшую эволюцию приложения.

Как Spring Modulith помогает организовать модульный монолит?

В библиотеке Spring Modulith есть множество механизмов, которые позволяют поддерживать модульность проекта. Вот некоторые из них:

Определения Модулей:

  • По умолчанию: Spring Modulith автоматически считает прямые подпакеты основного пакета приложения как отдельные модули.
  • Явное определение (опционально): Можно использовать аннотацию @ApplicationModule на package-info.java файле корневого пакета модуля для более явного определения и, если необходимо открыть внутренний пакет.
  • Публичный API модуля: По умолчанию, только типы, находящиеся непосредственно в корневом пакете модуля, считаются частью публичного API модуля. Все, что находится в подпакетах, считается внутренней реализацией и по умолчанию недоступно извне.

Верификации Модульной Структуры:

  • Spring Modulith интегрируется с фазой тестирования, позволяя проверять архитектурные правила во время сборки. Если вы нарушаете границы модуля, то тесты Modulith будут падать. Пример теста:
class ModularityTests { ApplicationModules modules = ApplicationModules.of(Application.class); @Test void verifiesModularStructure() { modules.verify(); } }
  • Генерация UML/C4-диаграмм на основе структуры модулей:
@Test void generateDocumentation() { new Documenter(modules) .writeModulesAsPlantUml() .writeIndividualModulesAsPlantUml(); }

Вывод этой генерации:

Как упростить работу с модульностью
  • Изолированное тестирование модулей: Мы можем писать интеграционные тесты (используется @ApplicationModuleTest), которые загружают только определенный модуль, а не все приложение. Это значительно ускоряет выполнение тестов и помогает убедиться в том, что модуль автономен и изолирован.

Взаимодействие между модулями

  • Вызовы через : Модули могут вызывать бины (сервисы, компоненты), которые находятся в корневом пакете другого модуля. Spring Modulith проверяет, что не пытаются получить доступ к внутренним классам других модулей.
  • Application Events: Spring Modulith предоставляет встроенную поддержку для асинхронных событий с помощью аннотации @ApplicationModuleListener. Также есть возможность сохранять события в базу данных в рамках текущей транзакции и публиковать их после коммита. Это гарантирует, что события не будут потеряны, при откате транзакции откатится. Плюс есть возможность публиковать события во внешние брокеры (RabbitMQ и т.п.). Если вы хотите построить Event Driven Architecture, то стоить начать с Application Events. (Вот статья, где расписывают подробнее как работать с событиями).

Заключение

Spring Modulith — это мощный инструмент, который помогает сфокусироваться на создании хорошо структурированных, поддерживаемых Spring Boot приложений. Используя его в сочетании с принципами разделения ответственности, инкапсуляции и событийной коммуникации, можно построить устойчивый и легко масштабируемый модульный монолит.

Мой канал в телеграм

Начать дискуссию