Миграция на Spring Boot 3.1.x. Update / Fix / Refactoring

Миграция на Spring Boot 3.1.x

  • Spring 6, Hibernate 6.2, Hibernate Validator 7, R2DBC 1.0, JPA 3.1, Tomcat 10
  • Java 17 – минимальная версия
  • Генерация нативных образов GraalVM
  • Улучшения в observability через Micrometer и Micrometer Tracing
  • Переход от Java EE к Jakarta EE. Jakarta EE 9 – минимальная версия, поддержка Jakarta EE 10

  • В pom.xml обновляем версии Spring и Springdoc
  • Мигрируем Springdoc на 2.x: меняется зависимости и пакет GroupedOpenApi.
  • Меняем зависимость jackson-datatype-hibernate5 на jackson-datatype-hibernate5-jakarta и в AppConfig заменяем Hibernate5Module на Hibernate5JakartaModule
  • В security antMatchers меняется на requestMatchers и нужно явно исключать swagger-ui из авторизации. Плюс добавилась миграция на Spring Security 6
  • ResponseEntityExceptionHandler теперь поддерживает спецификацию RFC-7807 - описание ошибок, перешел на нее в исключениях. В класс описания ошибок ProblemDetail можно добавлять свои поля: в GlobalExceptionHandler#handleMethodArgumentNotValid() добавил поле invalid_params. Однако при сериализации Jackson через поля, как у нас, в ответе это поле дублируется. Пришлось делать workaround: класс AppConfig.MixIn. Для обработки AppException сделал метод, возвращающий ProblemDetail
  • В AdminUserControllerTest не идут тесты на запросы со слешем в конце. Сделал отдельную переменную REST_URL_SLASH
  • Добавил исключения и поменял данные пользователей, как на стажировке TopJava
Spring Boot 3.0 Goes GA
What's New in Spring Framework 6.x
Spring Boot 3.0 Goes GA
Get ready for Spring Boot 3.0
The best way to do the Spring 6 migration
Spring Boot 3.0 Migration Guide
Spring Boot 3.1 Release Notes

Update / Fix / Refactoring

Update 05.11.24:

  • Перешел на LTS JDK 21 (не забудте поменять SDK в Project Structure... и сделать mvn clean + Refresh)
  • Обновил версии spring-boot-starter-parent (3.3.5), springdoc(2.6.0) и jsoup (1.18.1)
  • В новой версии Hibernate ElementCollection для User.roles не дружит с аннотациями JoinColumn и OnDelete, удалил их

Fix:

  • OpenApiConfig: исправил неверное имя приложения
  • SecurityFilterChain: подключил неиспользованный authenticationEntryPoint, перенес webSecurityCustomizer()/ignoring() в filterChain()/permitAll()
  • BaseEntity.id(): убрал дублирование (уже определен в default HasId.id()) и ненужный без HATEOAS Persistable

Refactoring:

  • Для средних и больших проектов более удобна организация пакетов по функционалу: сначала крупными мазками функционал, внутри него слои. Финальный код Spring Boot 3.x (BootJava) разбил по функционалу на app, common и user. Процесс творческий, на одном из проектов я попробовал использовать Spring Modulith и отказался от него, так как очень часто сущности делятся между разным функционалом и строгих границ не провести. "Суббота для человека, а не человек для субботы" в программировании звучит как: "Здравый смысл впереди строгой идеологии и архитектуры". Если будете соблюдать такую структуру в своем проекте - НЕ МЕЛЬЧИТЕ!
  • Equals and hashCode для BaseEntity сделал на основе решения от JPA Buddy
  • Для получения авторизованного пользователя из AuthUser выделил отдельный AuthUtil класс.
  • RestExceptionHandler - заменил специфичное BindException.getMessage() на "BindException".
    Неверные поля есть в invalid_params
  • User.roles сделал ненулевым
  • RestExceptionHandler - в вывод ошибки согласно RFC 7807 добавил title и instance(path)

Приглашаю на наши проекты и приятного кодинга!
Продолжение курса:

Стажировка TopJava   Наши курсы "Из Middle в Senior"

Присоединяйся к группе телеграмма JavaOPs

Если курс понравился - большая просьба сделать отзыв
или оценить звездочками этот курс на Udemy и/или Stepic