Spring АйО
8.43K subscribers
303 photos
209 videos
402 links
Русскоязычное сообщество Spring-разработчиков.

Habr: bit.ly/433IK46
YouTube: bit.ly/4h3Ci0x
VK: bit.ly/4hF0OG8
Rutube: bit.ly/4b4UeX6
Яндекс Музыка: bit.ly/3EIizWy

Канал для общения: @spring_aio_chat
Download Telegram
⚠️ Spring АйО x Amplicode

Эксперты сообщества Spring АйО уже в студии, на онлайн-митапе от команды Amplicode!

В мероприятии примут участие:
* Илья Сазонов
* Федор Сазонов
* Павел Кислов
* Рустам Курамшин
* Кирилл Толкачёв
* и другие!

Проверка оборудования уже завершена, а до начала прямого эфира осталось 5 минут – присоединяйтесь!

😄Трансляция в ВК
😉Трансляция на YouTube
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥96👎2
🐫 Underscore в имени Spring Data JPA методов

Все мы знаем, что для именования методов в java принято использовать lowerCamelCase. Но при определенных обстоятельствах правила можно и даже нужно нарушать! Например, когда в игру вступают фреймворки. Один такой пример мы сегодня с вами рассмотрим.

Предположим, у нас есть модель питомец-владелец питомца (многие-к-одному). Чтобы повысить перформанс нашего приложения, нам пришлось немного декомпозировать модель, добавив атрибут в класс питомца, в котором будет храниться информация о владельце – ownerLastName.

Класс питомца:

@Getter
@Setter
@Entity
@Table(name = "pet")
public class Pet {
@Id
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id")
private Owner owner;
@Column(name = "owner_last_name")
private String ownerLastName;
}


И класс владельца питомца:

@Getter
@Setter
@Entity
@Table(name = "owner")
public class Owner {
@Id
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@OneToMany(mappedBy = "owner", orphanRemoval = true)
private Set<Pet> pets = new LinkedHashSet<>();
}


Используя Spring Data JPA и derived методы нужно учитывать следующий нюанс. Получение списка питомцев по имени их владельца с выборкой именно по столбцу из таблицы с владельцами, а не по полю ownerLastName будет выглядеть следующим образом:

public interface PetRepository extends JpaRepository<Pet, Integer> {
List<Pet> findByOwner_LastName(String lastName);
}


Здесь нам пришлось правила именования и определить метод с "_" перед атрибутом. В этом случае Hibernate сгенерирует следующий запрос:

select *
from pet
left join owner on id=pet.owner_id
where owner.last_name=?


А если же мы хотим получить значения из таблицы pet, а не из owner, то нужно объявить метод без нижнего подчеркивания:

public interface PetRepository extends JpaRepository<Pet, Integer> {
List<Pet> findByOwnerLastName(String lastName);
}


Тогда поиск будет осуществлен по колонке из таблицы pet:

select *
from pet
where pet.owner_last_name=?


Подробнее про именование Spring Data JPA методов можно прочитать в документации.

P.S. А знаете ли вы ещё примеры подобного слома шаблонов?

#SpringTips #JPA
🔥37👍164🤔3
🛡 Подборка лучших материалов по Spring Security

Рады представить – Павел Кислов, эксперт сообщества Spring АйО, известный по своим выступлениям на JPoint про Spring Security и работу с гео-данными. Сегодня Павел решил поделиться с нами материалами, которые он считает отличными для полноценного погружения в Spring Security!

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

1. Плейлист по актуальному Spring Security от Laur Spilca (english)
2. Плейлист по старому Spring Security от него же (english)
3. Статья про CSRF
4. Статья про XSS
5. Статья про XXE
6. Доклад Сергея Васильева про XXE на пальцах
7. Простецкая статья про то из чего состоит filter chain
8. Доклад Михаила Вовренчука про OpenID Connect и OAuth2.0
9. Хорошая памятка по JWT
10. Статья про JWT на стороне клиента
11. Воркшоп "Spring Security, demystified by Daniel Garnier Moiroux" (english)
12. Книга "Spring Security in Action" (english)
13. Доклад "Everything new in Spring Security 6 baked with a Spring Boot 3 recipe by Laur Spilca" (english)
14. Официальная документация по Spring Security (english)
15. Официальный репозиторий тестовых примеров Spring Security на GitHub


🔖 Сохраняйте, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍46🔥20101🤯1
🗓 Еженедельный дайджест №12

Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!

Краткая история Java — вспомнили, с чего всё начиналось

Spring АйО х Amplicode — приняли участие в самом главном событии этой осени для Spring разработчиков

Underscore в имени Spring Data JPA методов разобрали один из нюансов, о котором нужно помнить во время написания derived методов

Подборка лучших материалов по Spring Security — Павел Кислов, эксперт сообщества Spring АйО, собрал все самые полезные материалы воедино

Какой IDE пользуетесь для разработки на Java/Spring — узнали, какую IDE предпочитают участники нашего сообщества

😌 @spring_aio
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥72👎1
2️⃣3️⃣ Что нового в Java 23?

Совсем скоро выйдет новая версия Java. Она будет содержать новые функции, улучшения, а некоторые устаревшие элементы будут удалены.

Например, некоторые из тех, что мы обозревали ранее:
- JEP 482: Гибкие конструкторы
- JEP 481: Scoped Values

А также те, про которые мы не успели рассказать (некоторые из них находятся в превью или инкубаторе):
- JEP 455: Примитивные типы в шаблонах pattern matching, instanceof и switch
- JEP 467: Поддержка Markdown в JavaDoc-комментариях
- JEP 476: Импортирование модулей
- JEP 466: Class-File API
- JEP 469: Vector API
- JEP 473: Stream Gatherers
- JEP 474: Сборщик мусора ZGC по умолчанию — generational
- JEP 477: Неявные классы и main-методы экземпляра класса
- JEP 480: Структурированный параллелизм

Подробнее про нововведения читайте в статье: https://axiomjdk.ru/announcements/2024/08/22/Java-23-preview/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥31👍75
⚡️ Плагины в IntelliJ IDEA – всё!

Судя по последнему опросу, бóльшая часть участников нашего сообщества используют IntelliJ IDEA как основную IDE для разработки на Java/Spring. Одной из причин симпатии к этой среде разработки со стороны разработчиков, на наш взгляд, являлись и являются плагины.

Однако несколько дней назад у пользователей с российскими IP-адрессами перестали устанавливаться плагины из официального маркетплейса JetBrains.

При попытке установить плагин появляется следующее сообщение:
К сожалению, в настоящее время мы не можем предоставлять вам наши продукты или услуги из-за правил экспортного контроля.


Решением этой проблемы, как и проблемы со скачиванием IntelliJ IDEA Ultimate, является переход на отличный от российского IP-адресс.

#SpringNews #IntelliJIDEA
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯41🔥13👍9🤔63👎1
✏️ Структурное логирование в Spring Boot 3.4

С выходом Spring Boot 3.4 логирование станет ещё удобнее: логи можно будет записывать в более унифицированном формате, что упростит их анализ и обработку.

В новом переводе от команды Spring АйО мы разберем основные шаги для настройки и использования этой технологии в проекте.

📚 Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/842226/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍62
😡 Spring Data JPA: Проблема N+1 и один из способов её решения

Одной из часто обсуждаемых тем на собеседованиях по Spring Data JPA является проблема N+1 и возможные способы её решения. Многие отвечают, что её можно решить с помощью join fetch или @EntityGraph. Однако это не всегда так.

Оба подхода действительно помогают, но только в простых случаях, когда нужно выбрать все записи из базы данных, как в следующих примерах:


@Query("""
select distinct a
from Author a
left join fetch a.books
""")
List<Author> findAllFetch();

@EntityGraph(attributePaths = {"books"})
@Query("""
select distinct a
from Author a
""")
List<Author> findAllFetch();


Но что если нужно выбрать только часть данных, например, постранично? Тогда запросы будут выглядеть так:


@Query("""
select a
from Author a
left join fetch a.books
""")
Slice<Author> findAllFetch(Pageable page);

@EntityGraph(attributePaths = {"books"})
@Query("""
select distinct a
from Author a
""")
List<Author> findAllFetch(Pageable page);


Проблема в том, что когда мы используем Pageable, Hibernate сначала загрузит все записи в память, а затем отсортирует их. Это может привести к OutOfMemoryError и/или серьёзной деградации производительности.

В защиту Hibernate отметим, что столь неоптимизированное действие он не станет выполнять "втихую" и выведет следующий warning в логах:


WARN: HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!


Более того, указав следующее свойство в application.properties/yaml, Hibernate и вовсе начнёт падать с JpaSystemException:


spring.jpa.properties.hibernate.query.fail_on_pagination_over_collection_fetch=true


Как же на самом деле стоит решать проблему N+1?

Правильное решение — использование аннотации @BatchSize:


@Entity
public class Owner extends Person {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
@BatchSize(size = 50)
private List<Pet> pets = new ArrayList<>();
}


Если коллекций много, можно настроить глобальный размер выборки в файле application.properties/yaml:


spring.jpa.properties.hibernate.default_batch_fetch_size=50


С использованием @BatchSize или глобального свойства запросы можно переписать следующим образом:


@Query("""
select a
from Author a
""")
Slice<Author> findAllFetch(Pageable page);

List<Author> findAll(Pageable pageable);


Вывод

Используйте @BatchSize или spring.jpa.properties.hibernate.default_batch_fetch_size, чтобы избежать проблемы N+1 без загрузки избыточного количества данных в память.

Стоит отметить, что используя этот подход важно помнить про необходимость обращения к элементам связанной коллекции в условиях наличия открытой транзакции, чтобы Hibernate смог загрузить необходимые данные. Несмотря на то, что spring.jpa.open-in-view=true позволяет нам быть уверенными в наличии открытой транзакции, он не является рекомендуемым.

Для более глубокого понимания оптимизации запросов рекомендуем ознакомиться с докладом экспертов сообщества Spring АйО – Ильи и Фёдора Сазоновых, с которым они выступали на последнем JPoint.

#SpringTips #JPA #DB
Please open Telegram to view this post
VIEW IN TELEGRAM
40👍19🔥15👎1
Поддержка CDS в Spring Boot и ожидания от Project Leyden

Spring Boot 3.3 раскрывает потенциал CDS (Class Data Sharing) благодаря двум новым функциям: самораспаковывающийся исполняемый JAR и поддержка Buildpacks CDS.

Команда Spring АйО перевела статью, в которой рассмотрены новые функции, нюансы их использования, а также их влияние на время запуска приложения.

📚 Читать на Хабре: https://habr.com/ru/companies/spring_aio/articles/842462/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍75
⚡️ IntelliJ IDEA 2024.3 EAP: Новые Возможности и Улучшения

Команда Spring АйО рада поделиться с вами свежей новостью от JetBrains: стала доступна первая EAP-версия IntelliJ IDEA 2024.3.

Среди нововведений:
🖥 Улучшения для java и kotlin
🤖 Прокаченный AI Assistant
А также улучшенный UX

📚 Подробнее читайте на Хабре: https://habr.com/ru/companies/spring_aio/articles/842854/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍83🤩3
📖 Бесплатные книги по SRE

Google выпустила серию книг по SRE, которые могут помочь тем, кто интересуется эксплуатацией и поддержкой современных приложений. В них содержатся теория и практические рекомендации, основанные на опыте инженеров Google.

- Building Secure & Reliable Systems: о важности безопасности в обеспечении надежности систем
- The Site Reliability Workbook: примеры применения принципов и практик SRE на практике
- Site Reliability Engineering: о пользе SRE на всех этапах жизненного цикла программного обеспечения

🔗 Прочитать книги бесплатно можно тут: https://sre.google/books/
🔥19👍65
🍿 Beyond The Success Of Kotlin / Документальный фильм от EngX

Почти 15 лет назад небольшая команда инженеров JetBrains приступила к, казалось бы, безумному начинанию — создать свой собственный язык программирования и добиться с ним успеха. В начале 2010-х годов Java был одним из самых популярных языков, которым пользовались миллионы инженеров. Но он не получал никаких серьезных обновлений в течение нескольких лет, и в нем не было новых функций. Разработчики искали новые решения.

Многие инженеры пытались предоставить альтернативу Java, создавая новые языки для JVM. Это стало небольшим окном возможностей для создания инструмента, который мог бы повлиять на всю отрасль. Так началась история Kotlin. Что привело к успеху Kotlin и чего это стоило команде? В этом документальном фильме вы услышите историю из первых уст.

😉 Смотреть на YT: https://www.youtube.com/watch?v=E8CtE7qTb-Q
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍106👎1
🗓 Еженедельный дайджест №13

Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!

Что нового в Java 23? — что нас ждет новое, а что станет deprecated в Java 23

Плагины в IntelliJ IDEA – всё! у пользователей с российскими IP-адрессами перестали устанавливаться плагины из официального маркетплейса JetBrains

Структурное логирование в Spring Boot 3.4 про основные шаги для настройки и использования логирования в Spring Boot 3.4

Spring Data JPA: Проблема N+1 и один из способов её решения — один из самых часто задаваемых вопросов - проблема N+1, а также про способы её решения

Поддержка CDS в Spring Boot и ожидания от Project Leyden о нововведениях Spring Boot 3.3, которые раскрывают потенциал CDS

IntelliJ IDEA 2024.3 EAP: Новые Возможности и Улучшения о новых возможностях в будущей мажорной версии IntelliJ IDEA 2024.3

Бесплатные книги по SRE серия книг от Google про техническое обеспечение надёжности сайтов

Beyond The Success Of Kotlin / Документальный фильм от EngX в новом документальном фильме узнали, что привело к успеху Kotlin и чего это стоило команде

😌 @spring_aio
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍10👌2
🐳 Эффективное управление окружениями с Docker Compose

В рамках разработки приложений часто возникает необходимость в создании нескольких окружений. Например, окружение для продакшена и девелопмента. Эти окружения могут отличаться по конфигурациям, инструментам и сервисам, необходимым для работы.

Предположим, что мы хотим разработать окружения для Spring Boot приложения, использующего PostgreSQL и Kafka:
* Для продакшена: минимальный набор сервисов – Spring Boot, PostgreSQL и Kafka.
* Для разработки: расширенный набор, Spring Boot, PostgreSQL, Kafka и удобные инструменты для работы, такие как pgAdmin и KafkaUI.

Мы рассмотрим решение этой задачи в контексте использования Docker Compose. Отметим, что в большинстве случаев для продакшена рекомендуется использовать более продвинутые решения, например, Kubernetes.

Возможные способы решения поставленной задачи

1. Один файл с профилями
Можно описать все сервисы в одном docker-compose.yml и использовать профили для разделения сервисов, необходимых в продакшене и разработке. Такой подход позволит легко управлять сервисами, активируя нужные профили в зависимости от окружения.

Преимущества:
* Один файл для управления всеми сервисами.
* Легкость переключения между окружениями за счёт использования профилей.

Недостатки:
* Отсутствие гибкости: сложно настроить разные порты, скрипты инициализации для сервисов в разных окружениях.
* Не всегда удобен для сложных конфигураций.

2. Дублирование файлов

Преимущества:
* Полная гибкость в настройке каждого окружения.
* Можно легко добавить уникальные параметры и сервисы для каждого случая.

Недостатки:
* Дублирование кода.
* Сложность синхронизации изменений между файлами.
* Проблемы с поддержкой нескольких файлов (например, при добавлении нового сервиса).

3. Переиспользование сервисов с include и extends

Возможно, не все знают, но Docker Compose предоставляет ключевые слова include и extends, которые могут отлично подойти для нашей задачи. Эти конструкции позволяют избежать дублирования кода, переиспользуя общие сервисы между различными файлами.

* Include даёт возможность подключить один docker compose файл к другому, аналогично запуску нескольких файлов через терминал. Этот способ полезен, если нам нужно просто включить сервисы без дополнительных изменений.
* Extends – более гибкий инструмент, который позволяет подключить сервисы из одного файла в другой и переопределить их свойства, что особенно удобно, если требуется настроить окружение под разные нужды.

Преимущества:
* Избегаем дублирования кода.
* Гибкость при настройке сервисов в разных окружениях.
* Возможность вынести общие сервисы в отдельный файл и изменять их конфигурации в каждом окружении.

Недостатки:
* Сложнее в реализации и поддержке по сравнению с одним файлом с профилями.
* Потребуются дополнительные знания о синтаксисе docker-compose.

services.yml (общие сервисы)


version: '3.8'
services:
postgres:
image: postgres:13
kafka:
image: bitnami/kafka:latest


docker-compose.prod.yml:


version: '3.8'
services:
spring:
image: my-spring-app:latest
postgres:
extends:
file: services.yml
service: postgres
kafka:
extends:
file: services.yml
service: kafka


docker-compose.dev.yml:


version: '3.8'
services:
postgres:
extends:
file: services.yml
service: postgres
kafka:
extends:
file: services.yml
service: kafka
pgadmin:
image: dpage/pgadmin4
kafka-ui:
image: provectuslabs/kafka-ui


Таким образом, extends позволяет нам гибко конфигурировать окружения и при этом не дублировать код, что делает этот способ наиболее подходящим для нашей задачи.

Ставь ❤️ если знал про extends/include и 🔥 если не знал

#DockerCompose #Tips
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥80👍1412🤯2