Please open Telegram to view this post
VIEW IN TELEGRAM
Spring Reactor. Эволюция сервисов. На пути к реактивности
Это статья описывает опыт миграции традиционного приложения java spring на Spring reactor стек. О специфике разрабатываемой информационной системы, уже подробно рассказывал. Кратко о системе - смешанная сервисно-микросервисная архитектура. Чтобы получить бизнес результат, требуется вызвать микросервис, который вызывает сервис, который вызывает набор микросервисов для формирования ценностного набора данных. Получается цепочка вызовов. Сервисы и микросервисы разрабатывались на традиционном технологическом стеке, без использования реактивного подхода.
Читать статью
Это статья описывает опыт миграции традиционного приложения java spring на Spring reactor стек. О специфике разрабатываемой информационной системы, уже подробно рассказывал. Кратко о системе - смешанная сервисно-микросервисная архитектура. Чтобы получить бизнес результат, требуется вызвать микросервис, который вызывает сервис, который вызывает набор микросервисов для формирования ценностного набора данных. Получается цепочка вызовов. Сервисы и микросервисы разрабатывались на традиционном технологическом стеке, без использования реактивного подхода.
Читать статью
VK
Spring Reactor. Эволюция сервисов. На пути к реактивности
Контекст
Проверяемые исключения (Checked Exceptions)
Непроверяемые исключения (Unchecked Exceptions)
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Java Guru 🤓
Что будет результатом кода?
Anonymous Quiz
24%
Ошибка компиляции
4%
RuntimeException
59%
1 2 3 4
3%
1| 2| 3| 4|
10%
ClassCastException
Please open Telegram to view this post
VIEW IN TELEGRAM
Никогда не используй CascadeType.ALL вместе с @ManyToMany | Amplicode
Использовать CascadeType.ALL для @ManyToMany не рекомендуется, так как это может привести к непредсказуемым результатам во время удаления JPA сущностей. Вместо этого следует использовать CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST и CascadeType.REFRESH.
🌐 🗣 СМОТРЕТЬ VKVIDEO
📺 🗣 СМОТРЕТЬ RUTUBE
📝 🗣 СМОТРЕТЬ DZEN
Использовать CascadeType.ALL для @ManyToMany не рекомендуется, так как это может привести к непредсказуемым результатам во время удаления JPA сущностей. Вместо этого следует использовать CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST и CascadeType.REFRESH.
Please open Telegram to view this post
VIEW IN TELEGRAM
Как работает CopyOnWriteArrayList под капотом?
CopyOnWriteArrayList — это потокобезопасная реализация списка, оптимизированная для сценариев с частым чтением и редкими изменениями. Когда происходит изменение в CopyOnWriteArrayList, создаётся новая копия базового массива, в которую вносятся изменения. Таким образом, чтение и запись изолированы: до завершения модификации читающие потоки получают доступ к старому массиву, а запись завершает свою работу, не блокируя других потоков.
💡 Основные механизмы:
🟡 До завершения операции модификации все читающие потоки продолжают работать с текущей неизменяемой версией массива.
🟡 При вызове методов, изменяющих список (например, add, remove), создаётся новый массив на основе старого. Изменения применяются именно к новому массиву.
🟡 После завершения модификации ссылка на массив обновляется на новую версию. Теперь все новые операции чтения будут работать с обновлённой версией.
⚠️ Особенности:
🟢 Высокие накладные расходы на запись из-за создания копий.
🟢 Подходит для случаев, где чтение доминирует над изменением.
🟢 Не рекомендуется для сценариев с частыми обновлениями из-за увеличения потребления памяти.
CopyOnWriteArrayList идеально подходит для кешей, обработчиков событий и других структур данных, где важна стабильность чтения при редких изменениях.
Документация
✅ Java библиотека #java
CopyOnWriteArrayList — это потокобезопасная реализация списка, оптимизированная для сценариев с частым чтением и редкими изменениями. Когда происходит изменение в CopyOnWriteArrayList, создаётся новая копия базового массива, в которую вносятся изменения. Таким образом, чтение и запись изолированы: до завершения модификации читающие потоки получают доступ к старому массиву, а запись завершает свою работу, не блокируя других потоков.
CopyOnWriteArrayList идеально подходит для кешей, обработчиков событий и других структур данных, где важна стабильность чтения при редких изменениях.
Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Это наглядная дорожная карта для изучения java в 2025 году!
Please open Telegram to view this post
VIEW IN TELEGRAM
Паттерн Посетитель (Visitor)
Visitor — это поведенческий паттерн, который позволяет добавлять новые операции к объектам без изменения их классов. Он выделяет операции в отдельный объект, называемый "посетитель", что позволяет избежать дублирования кода и поддерживать open/closed архитектуру.
Использование:
🟡 Когда нужно добавлять новые операции к иерархии классов без изменения их структуры.
🟡 Когда объектам требуется обработка, зависящая от их типов, но нежелательно добавлять логику внутрь самих классов.
Преимущества:
1️⃣ Упрощает добавление новых операций.
2️⃣ Логика работы концентрируется в одном месте, а не размазывается по классам.
3️⃣ Сохраняется открытость к изменениям операций и закрытость классов к модификациям.
Недостатки:
1️⃣ Увеличивает количество классов.
2️⃣ Добавление нового типа в иерархию требует обновления всех существующих посетителей.
3️⃣ Работает лучше всего с фиксированной иерархией.
📌 Visitor идеально подходит для сценариев, где требуется частое добавление новых операций при сохранении стабильности классов.
✅ Java библиотека #java
Visitor — это поведенческий паттерн, который позволяет добавлять новые операции к объектам без изменения их классов. Он выделяет операции в отдельный объект, называемый "посетитель", что позволяет избежать дублирования кода и поддерживать open/closed архитектуру.
Использование:
Преимущества:
Недостатки:
Please open Telegram to view this post
VIEW IN TELEGRAM
Контейнеризация Spring Boot приложений | Оптимальный Docker Image | Amplicode
Оптимальный образ для Spring Boot приложения даёт множество преимуществ, среди которых можно отметить:
✨ меньший размер финального образа (из-за исключения инструментов сборки и использования JRE вместо JDK);
🛡 более безопасный подход к работе с файловой системой (за счёт создания и использования пользователя с ограниченными правами);
🚀 ускоренный процесс сборки (благодаря кэшированию зависимостей).
Amplicode позволяет сгенерировать такой образ за пару кликов!
🌐 🗣 СМОТРЕТЬ VKVIDEO
📺 🗣 СМОТРЕТЬ RUTUBE
📝 🗣 СМОТРЕТЬ DZEN
Оптимальный образ для Spring Boot приложения даёт множество преимуществ, среди которых можно отметить:
✨ меньший размер финального образа (из-за исключения инструментов сборки и использования JRE вместо JDK);
🛡 более безопасный подход к работе с файловой системой (за счёт создания и использования пользователя с ограниченными правами);
🚀 ускоренный процесс сборки (благодаря кэшированию зависимостей).
Amplicode позволяет сгенерировать такой образ за пару кликов!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Как устроен под капотом LinkedHashSet?
LinkedHashSet — это коллекция, обеспечивающая хранение уникальных элементов с сохранением порядка их вставки. LinkedHashSet, как и HashSet, работает с элементами за амортизированное O(1) время, но, в отличие от HashSet, сохраняет порядок добавления элементов благодаря дополнительной структуре связного списка.
🟡 Структура LinkedHashSet
LinkedHashSet базируется на HashMap, но имеет уникальную особенность — упорядочивание элементов за счёт использования связного списка поверх стандартной хеш-таблицы.
🟢 Хранение данных: LinkedHashSet использует LinkedHashMap для хранения элементов. Каждый добавляемый элемент выступает в роли ключа, а значение всегда фиксировано (обычно это объект-заглушка).
🟢 Связный список: Для поддержания порядка добавления, элементы связаны друг с другом в виде двусвязного списка. Это позволяет итерациям проходить элементы в порядке их вставки.
🟢 Уникальность элементов: Как и в HashSet, каждый элемент уникален. При попытке добавить дублирующий элемент он игнорируется, сохраняя уникальность всех значений.
🟡 Производительность
🟢 Добавление: Добавление элементов происходит за амортизированное O(1) время. LinkedHashSet вычисляет хэш элемента и индекс, где он будет храниться в массиве бакетов LinkedHashMap.
🟢 Удаление: Удаление происходит также за амортизированное O(1) время. LinkedHashSet находит элемент по хэшу, удаляет его из связного списка и освобождает место в корзине.
🟢 Поиск: Поиск происходит за амортизированное O(1) время благодаря хэш-таблице.
🟡 Использование памяти
LinkedHashSet требует немного больше памяти по сравнению с HashSet, так как хранит не только хэш-таблицу, но и двусвязный список, поддерживающий порядок добавления элементов. Это делает LinkedHashSet более затратным в плане памяти, особенно при большом количестве элементов.
🟡 Преимущества и недостатки
🟢 Преимущества:
- Сохранение порядка добавления элементов.
- Быстрая работа с элементами за амортизированное O(1) время, как и в HashSet.
🟢 Недостатки:
- Потребление ресурсов возрастает при большом количестве элементов, так как структура требует больше памяти для поддержания порядка.
✅ Java библиотека #java
LinkedHashSet — это коллекция, обеспечивающая хранение уникальных элементов с сохранением порядка их вставки. LinkedHashSet, как и HashSet, работает с элементами за амортизированное O(1) время, но, в отличие от HashSet, сохраняет порядок добавления элементов благодаря дополнительной структуре связного списка.
LinkedHashSet базируется на HashMap, но имеет уникальную особенность — упорядочивание элементов за счёт использования связного списка поверх стандартной хеш-таблицы.
LinkedHashSet требует немного больше памяти по сравнению с HashSet, так как хранит не только хэш-таблицу, но и двусвязный список, поддерживающий порядок добавления элементов. Это делает LinkedHashSet более затратным в плане памяти, особенно при большом количестве элементов.
- Сохранение порядка добавления элементов.
- Быстрая работа с элементами за амортизированное O(1) время, как и в HashSet.
- Потребление ресурсов возрастает при большом количестве элементов, так как структура требует больше памяти для поддержания порядка.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое BeanPostProcessor в Spring?
BeanPostProcessor — это интерфейс из Spring Framework, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring контейнере. Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:
🟡 postProcessBeforeInitialization(Object bean, String beanName) - вызывается до того, как бин будет инициализирован (до вызова метода @PostConstruct или InitializingBean#afterPropertiesSet).
🟡 postProcessAfterInitialization(Object bean, String beanName) - вызывается после инициализации бина (после завершения всех инициализационных методов).
Зачем нужен BeanPostProcessor?
Он используется для дополнительной обработки и кастомизации бинов после их создания, но до передачи клиентскому коду. Примеры:
- Добавление проксирования бинов (например, для AOP или транзакций).
- Валидация или изменение свойств бинов.
- Логирование жизненного цикла.
- Добавление кастомных аннотаций.
- Обработка маркерных интерфейсов.
Как это работает?
1️⃣ Spring сканирует контекст на наличие бинов, реализующих интерфейс BeanPostProcessor.
2️⃣ Если такие бины найдены, они применяются ко всем бинам в приложении.
3️⃣ Методы postProcessBeforeInitialization и postProcessAfterInitialization вызываются для каждого бина, который создаёт Spring.
Результат: Вывод сообщений о каждом бине до и после инициализации.
✅ Java библиотека #java
BeanPostProcessor — это интерфейс из Spring Framework, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring контейнере. Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:
Зачем нужен BeanPostProcessor?
Он используется для дополнительной обработки и кастомизации бинов после их создания, но до передачи клиентскому коду. Примеры:
- Добавление проксирования бинов (например, для AOP или транзакций).
- Валидация или изменение свойств бинов.
- Логирование жизненного цикла.
- Добавление кастомных аннотаций.
- Обработка маркерных интерфейсов.
Как это работает?
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("Before Initialization: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("After Initialization: " + beanName);
return bean;
}
}
Результат: Вывод сообщений о каждом бине до и после инициализации.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Умная инжекция и автодополнение методов | Spring Data JPA Repository | Amplicode
🌐 🗣 СМОТРЕТЬ VKVIDEO
📺 🗣 СМОТРЕТЬ RUTUBE
📝 🗣 СМОТРЕТЬ DZEN
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое BeanFactoryPostProcessor в Spring?
BeanFactoryPostProcessor — это интерфейс из Spring Framework, который позволяет вмешиваться в процесс создания бинов в BeanFactory до их инициализации, но после того, как Spring их создал. Он предоставляет один основной метод:
🔘 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) — вызывается до инициализации бинов. В этом методе можно изменять конфигурацию бинов, например, добавлять или изменять их свойства, влиять на их типы или даже на порядок их создания.
Зачем нужен BeanFactoryPostProcessor?
Он используется для того, чтобы дать возможность кастомизировать настройки Spring контейнера, не вмешиваясь в сам процесс создания объектов. Примеры:
- Изменение параметров конфигурации бинов, которые уже были определены в контексте.
- Использование кастомных значений или свойств для бинов до их создания.
- Управление зависимостями на уровне контейнера.
- Добавление пользовательских конфигураций, таких как создание собственных PropertyEditors или манипуляции с BeanDefinition.
Как это работает?
1️⃣ Spring сканирует контекст на наличие бинов, реализующих интерфейс BeanFactoryPostProcessor.
2️⃣ Эти бины выполняются до создания бинов в контейнере, и вы можете изменить BeanDefinition в контейнере.
3️⃣ Вы можете, например, изменять параметры и настройки бинов, задавать или корректировать их зависимости, которые будут использованы при создании бинов Spring.
Пример реализации:
В этом примере изменяются настройки существующего бина до его создания, что позволяет управлять его поведением в контейнере.
✅ Java библиотека #java
BeanFactoryPostProcessor — это интерфейс из Spring Framework, который позволяет вмешиваться в процесс создания бинов в BeanFactory до их инициализации, но после того, как Spring их создал. Он предоставляет один основной метод:
Зачем нужен BeanFactoryPostProcessor?
Он используется для того, чтобы дать возможность кастомизировать настройки Spring контейнера, не вмешиваясь в сам процесс создания объектов. Примеры:
- Изменение параметров конфигурации бинов, которые уже были определены в контексте.
- Использование кастомных значений или свойств для бинов до их создания.
- Управление зависимостями на уровне контейнера.
- Добавление пользовательских конфигураций, таких как создание собственных PropertyEditors или манипуляции с BeanDefinition.
Как это работает?
Пример реализации:
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Пример изменения beanDefinition
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("someBean");
beanDefinition.getPropertyValues().add("someProperty", "newValue");
}
}
В этом примере изменяются настройки существующего бина до его создания, что позволяет управлять его поведением в контейнере.
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Знакомство с Micronaut
Пример CRUD приложения на Micronaut.
🌐 🗣 СМОТРЕТЬ VKVIDEO
📺 🗣 СМОТРЕТЬ RUTUBE
📝 🗣 СМОТРЕТЬ DZEN
✅ Java библиотека #java
Пример CRUD приложения на Micronaut.
Please open Telegram to view this post
VIEW IN TELEGRAM
23 шаблона проектирования для 99% разработчиков на Java
В этом исчерпывающем руководстве мы изучим все важные шаблоны ООП для написания кода.
Шаблоны проектирования — это испытанный способ решения проблемы в заданном контексте. Они скорее открыты, нежели придуманы, что очевидно и из применения слова «шаблон». Используя шаблон проектирования, вы получаете знания всех сообществ для безопасного решения этой проблемы.
Читать статью
В этом исчерпывающем руководстве мы изучим все важные шаблоны ООП для написания кода.
Шаблоны проектирования — это испытанный способ решения проблемы в заданном контексте. Они скорее открыты, нежели придуманы, что очевидно и из применения слова «шаблон». Используя шаблон проектирования, вы получаете знания всех сообществ для безопасного решения этой проблемы.
Читать статью
VK
23 шаблона проектирования для 99% разработчиков на Java
В этом исчерпывающем руководстве мы изучим все важные шаблоны ООП для написания кода.