Spring Boot — самая популярная среда Java для разработки микросервисов. В этой статье я поделюсь с вами лучшими практиками, которые я принял с 2016 года для использования Spring Boot в профессиональной разработке. Они основаны на моем личном опыте и статьях некоторых известных экспертов по Spring Boot.
В этой статье я сосредоточусь на методах, специфичных для Spring Boot (и в большинстве случаев также применим к проектам Spring). Лучшие практики перечислены ниже в произвольном порядке.
1. Используйте настраиваемую спецификацию для поддержки сторонних зависимостей
Эта практика основана на моем опыте работы в реальных проектах.
Сам проект Spring Boot использует и интегрирует большое количество проектов с открытым исходным кодом, которые помогают нам поддерживать эти сторонние зависимости. Но некоторые не включены в фактическое использование проекта, что требует от нас поддержки версии в проекте. Если большой проект включает в себя множество неразработанных модулей, его будет очень сложно поддерживать.
Как это сделать? На самом деле Spring IO Platform делает именно это, поскольку сама является подпроектом Spring Boot и поддерживает другие сторонние библиотеки с открытым исходным кодом. Мы можем научиться на Spring IO Platform, чтобы написать нашу собственную базовую платформу проекта, и все проекты бизнес-модулей должны быть представлены в форме спецификации. Таким образом, при обновлении сторонней зависимости вам нужно обновить только версию этой зависимости.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Cairo-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. Используйте автоматическую настройку
Главной особенностью Spring Boot является использование автоконфигурации. Это часть Spring Boot, которая упрощает ваш код и заставляет его работать. Автоконфигурация активируется, когда в пути к классам обнаруживается определенный файл jar.
Самый простой способ использовать его — положиться на Spring Boot Starters. Поэтому, если вы хотите интегрироваться с Redis, вы можете сначала включить:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Если вы хотите интегрироваться с MongoDB, вам нужно это:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
С помощью этих стартеров эти утомительные конфигурации хорошо интегрируются и работают вместе, и все они протестированы и проверены. Это очень помогает избежать ужасного ада Jar.
Определенные классы конфигурации можно исключить из автоматической настройки с помощью следующих атрибутов аннотаций:
@EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class})
Но это должно быть сделано только при абсолютно необходимо.
Официальную документацию по автоконфигурации можно найти здесь:
3. Используйте Spring Initializr для запуска нового проекта Spring Boot.
Это передовая практика от Джоша Лонга (Spring Advocate, @starbuxman).
Spring Initializr предоставляет очень простой способ создать новый проект Spring Boot и загрузить возможные зависимости в соответствии с вашими потребностями.
Создание приложения с использованием initializr гарантирует, что вы получите зависимости для тестирования и проверки, эти зависимости применяются к конфигурации Spring Automatic. Вы даже можете найти какую-то новую интеграцию, но вы можете не знать об этом.
4. Рассмотрите возможность создания собственных автоматических конфигураций для распространенных организационных проблем.
Это также исходит от Джоша Лонга (Spring Advocate, @starbuxman) — эта практика предназначена для опытных пользователей.
Если вы работаете в компании или команде, которая сильно зависит от Spring Boot и вам нужно решить общие проблемы, вы можете создать свою собственную автоматическую настройку.
Эта задача требует много работы, поэтому вам нужно подумать, когда преимущества стоят вложенных средств. Легче поддерживать одну автоматическую конфигурацию, чем несколько слегка различающихся пользовательских конфигураций.
Если эта предоставленная конфигурация Spring Boot будет выпущена как библиотека с открытым исходным кодом, это значительно упростит работу по настройке для тысяч пользователей.
5. Правильно спроектируйте структуру каталогов кода
Несмотря на это, у вас есть большая свобода, но есть несколько основных правил, которым стоит следовать при разработке структуры исходного кода.
Избегайте использования пакетов по умолчанию. Убедитесь, что все (включая вашу точку входа) находится в хорошо названном пакете, чтобы избежать неожиданностей, связанных со сборкой и сканированием компонентов;
Держите Application.java (класс входа приложения) в исходном каталоге верхнего уровня;
Я рекомендую размещать контроллеры и сервисы в функционально-ориентированных модулях, но это необязательно. Некоторые очень хорошие разработчики рекомендуют собрать все контроллеры вместе. Несмотря ни на что, придерживайтесь одного стиля!
6. Держите @Controller кратким и сфокусированным
Контроллер должен быть очень простым. Вы можете прочитать о разделе паттернов контроллера в GRASP здесь. Вы хотите, чтобы контроллер действовал как координатор и делегат, а не выполнял фактическую бизнес-логику. Вот основные практики:
- Контроллер должен быть без гражданства! По умолчанию контроллер является одним вариантом осуществления, любым состоянием и может вызвать ряд проблем;
- Контроллеры не должны выполнять бизнес-логику, а полагаться на делегатов;
- Контроллер должен обрабатывать HTTP-уровень приложения, это не должно передаваться службе;
- Контроллеры должны быть разработаны с учетом вариантов использования/бизнес-возможностей.
Чтобы погрузиться в этот контент, вам нужно больше узнать о передовых методах разработки REST API. Стоит узнать, хотите ли вы использовать Spring Boot или нет.
7. Постройте @Service вокруг бизнес-функций
Служба — еще одна основная концепция Spring Boot. Я считаю, что лучше всего структурировать услуги вокруг бизнес-функций/доменов/вариантов использования (как бы вы их ни называли).
Создайте свое приложение с именем, похожим наAccountService
, UserService
, PaymentService
Такая услуга по сравнению сDatabaseService
,ValidationService
,CalculationService
Это было бы более уместно.
Вы можете решить использовать сопоставление «один к одному» между контроллером и сервисом, это было бы идеально. Но это не значит, что сервисы не могут звонить друг другу!
8. Сделайте базу данных независимой от основной бизнес-логики
Я не уверен, как обрабатывать взаимодействия с базой данных в Spring Boot. После прочтения «Чистой архитектуры» Роберта С. Мартина мне это станет ясно.
Вы хотите, чтобы логика вашей базы данных была отделена от службы. В идеале вы не хотите, чтобы служба знала, с какой базой данных она взаимодействует, что требует некоторой абстракции для инкапсуляции постоянства объектов.
Роберт С. Мартин решительно заявляет, что ваша база данных является «деталью», что означает отсутствие связи вашего приложения с конкретной базой данных. В прошлом немногие люди переключались между базами данных, и я заметил, что использование Spring Boot и современная разработка микросервисов значительно ускоряют работу.
9. Держите бизнес-логику подальше от кода Spring Boot
Учитывая уроки «Чистой архитектуры», вы также должны защитить свою бизнес-логику. Очень заманчиво смешивать все виды кода Spring Boot вместе... не делайте этого. Если вы сможете устоять перед искушением, вы сможете повторно использовать свою бизнес-логику.
Частью службы обычно становится библиотека. Легче создавать, не удаляя множество аннотаций Spring из кода.
10. Рекомендуется внедрение конструктора
Эту практику придумал Фил Уэбб (руководитель проекта Spring Boot, @phillip_webb).
Один из способов защитить вашу бизнес-логику от кода Spring Boot — использовать внедрение конструктора. не только потому, что@Autowired
Аннотации являются необязательными для конструктора, а также упрощают создание экземпляров bean-компонентов без Spring.
11. Знаком с моделью параллелизма
Одна из самых популярных статей, которые я написал, — «Введение в параллелизм в Spring Boot». Я думаю, причина этого в том, что это поле часто неправильно понимают и игнорируют. Проблемы могут возникнуть при неправильном использовании.
В Spring Boot Controller и Service по умолчанию являются синглтонами. Это может привести к возможным проблемам параллелизма, если вы не будете осторожны. Вы также обычно имеете дело с ограниченным пулом потоков. Пожалуйста, ознакомьтесь с этими понятиями.
Если вы используете новый приложение WebFlux Style Spring Boot, я объяснил, как работает в «Параллерии WebFlux / Reactor Prience WebFlux / Reactor и Backpruce».
12. Усиление экстернализации управления конфигурацией
Это выходит за рамки Spring Boot, хотя это обычная проблема, когда люди начинают создавать несколько похожих сервисов...
Вы можете управлять конфигурацией своего приложения Spring вручную. Если вы имеете дело с несколькими приложениями Spring Boot, вам необходимо сделать управление конфигурацией более мощным.
Я рекомендую два основных подхода:
- Используйте сервер конфигурации, такой как Spring Cloud Config;
- Сохраните всю конфигурацию в переменных среды (можно настроить на основе репозитория git).
Любой из этих вариантов (второй вариант немного сложнее) требует от вас меньше работы в DevOps, но это довольно распространено в мире микросервисов.
13. Обеспечьте глобальную обработку исключений
Вам действительно нужен последовательный способ обработки исключений. Spring Boot предлагает два основных подхода:
- Вы должны использовать HandlerExceptionResolver для определения глобальной стратегии обработки исключений;
- Вы также можете добавить к контроллеру аннотацию @ExceptionHandler, которая может быть полезна в некоторых конкретных сценариях.
Это почти то же самое, что и в Spring, и у Baeldung есть подробная статья об обработке ошибок в REST и Spring, которую стоит прочитать.
14. Используйте структуру ведения журнала
Вы, вероятно, уже знаете об этом, но вам следует использовать Logger для ведения журнала, а не делать это вручную с помощью System.out.println(). Это легко сделать в Spring Boot практически без настройки. Просто получите экземпляр регистратора класса:
Logger logger = LoggerFactory.getLogger(MyClass.class);
Это важно, потому что позволяет вам устанавливать различные уровни ведения журнала в соответствии с вашими потребностями.
15. Протестируйте свой код
Это не относится к Spring Boot, но требует напоминания — протестируйте свой код! Если вы не пишете тесты, вы с самого начала пишете унаследованный код.
Если кто-то другой использует вашу кодовую базу, изменение чего-либо в ней станет опасным. Это может быть еще более рискованным, если у вас есть несколько служб, которые зависят друг от друга.
Поскольку существуют лучшие практики Spring Boot, вам следует рассмотреть возможность использования Spring Cloud Contract для ваших контрактов, ориентированных на потребителя, это упростит вашу интеграцию с другими службами.
16. Используйте тестовые срезы, чтобы сделать тестирование более простым и целенаправленным
Эту практику придумал Мадхура Бхаве (разработчик Spring, @madhurabhave23).
Тестирование кода с помощью Spring Boot может быть сложным — вам нужно инициализировать уровень данных, подключить множество сервисов, смоделировать вещи... на самом деле это не так уж сложно! Ответ заключается в использовании тестовых срезов.
С тестовыми слайсами вы можете подключать только части приложения по мере необходимости. Это может сэкономить вам много времени и гарантировать, что ваши тесты не будут связаны с неиспользуемым контентом. Сообщение в блоге от spring.io под названием Custom test slice with Spring test 1.4 объясняет эту технику.
Суммировать
Благодаря Spring Boot написание микросервисов на базе Spring стало еще проще. Я надеюсь, что благодаря этим передовым методам ваш процесс внедрения станет не только более быстрым, но и более сильным и успешным в долгосрочной перспективе. удачи!