Beyond Loom: Weaving new concurrency patterns
В этой статье мы обсудим некоторые новые паттерны для параллельных систем, которые стали возможны благодаря новой функции виртуальных потоков в Java 21, а также некоторые связанные с ней функции, которые "следуют" за виртуальными потоками - в частности, Structured Concurrency (JEP 453) и Scoped Values (JEP 446).
Обратите внимание, что в JDK 21 структурированный параллелизм и скопированные значения находятся в состоянии Preview и поэтому не могут быть использованы в продакшен-приложениях.
Учитывая это ограничение, давайте начнем с рассмотрения паттернов, которые поддерживаются только виртуальными потоками и, следовательно, могут без ограничений использоваться в приложениях Java 21.
https://developers.redhat.com/articles/2023/10/03/beyond-loom-weaving-new-concurrency-patterns#
👉@BookJava
В этой статье мы обсудим некоторые новые паттерны для параллельных систем, которые стали возможны благодаря новой функции виртуальных потоков в Java 21, а также некоторые связанные с ней функции, которые "следуют" за виртуальными потоками - в частности, Structured Concurrency (JEP 453) и Scoped Values (JEP 446).
Обратите внимание, что в JDK 21 структурированный параллелизм и скопированные значения находятся в состоянии Preview и поэтому не могут быть использованы в продакшен-приложениях.
Учитывая это ограничение, давайте начнем с рассмотрения паттернов, которые поддерживаются только виртуальными потоками и, следовательно, могут без ограничений использоваться в приложениях Java 21.
https://developers.redhat.com/articles/2023/10/03/beyond-loom-weaving-new-concurrency-patterns#
👉@BookJava
👍5👏1
🚀 Советы по Spring Boot 💡
Библиотека Spring Boot Startup Report генерирует интерактивный отчет о запуске приложения Spring Boot, который позволяет понять, что влияет на время запуска приложения, и, возможно, поможет его оптимизировать. 🔥
https://github.com/maciejwalkowiak/spring-boot-startup-report
👉@BookJava
Библиотека Spring Boot Startup Report генерирует интерактивный отчет о запуске приложения Spring Boot, который позволяет понять, что влияет на время запуска приложения, и, возможно, поможет его оптимизировать. 🔥
https://github.com/maciejwalkowiak/spring-boot-startup-report
👉@BookJava
👍8🔥6
Как вызвать транзакционный метод из того же класса?
В Spring Framework существует аннотация
В теории,
Это происходит вследствие того, что по умолчанию Spring AOP добавляет код открытия/закрытия транзакции через динамический proxy класс. То есть, вместо Foo инджектится нечто, похожее на код на изображении.
Первый вариант решения проблемы – вместо аннотации использовать TransactionTemplate, то есть обернуть код в транзакцию вручную. Примеры использования можно посмотреть в этой статье.
Другой, более универсальный, но более сложный в конфигурации способ – переключить режим работы Spring AOP с динамических прокси на нечто другое. Обычно применяется библиотека AspectJ:
В Spring AOP есть понятие weaving – этап добавления дополнительной функциональности (аспектов). В нашем случае, это код открытия/закрытия транзакции. Чтобы заработал weaving AspectJ этапа компиляции, в сборку нужно добавить плагин: aspectj-maven-plugin для maven, gradle-aspectj для gradle.
Подробнее об экспериментах с разными режимами Spring AOP можно почитать в статье на хабре.
👉@BookJava
В Spring Framework существует аннотация
@Transactional
. Ей помечается метод или класс, весь код которого должен выполняться в рамках транзакции. Обычно имеется в виду транзакция базы данных, но вообще это понятие определяется используемым transactionManager-ом. Настройки, такие как уровень изоляции, стратегия роллбэка и прочие, определяются через параметры этой аннотации.В теории,
@Transactional
делает метод транзакционным для этого класса и всех его наследников. На практике же, по умолчанию, если вызвать транзакционный метод Foo.bar() из Foo.baz(), то транзакция не создастся.Это происходит вследствие того, что по умолчанию Spring AOP добавляет код открытия/закрытия транзакции через динамический proxy класс. То есть, вместо Foo инджектится нечто, похожее на код на изображении.
Первый вариант решения проблемы – вместо аннотации использовать TransactionTemplate, то есть обернуть код в транзакцию вручную. Примеры использования можно посмотреть в этой статье.
Другой, более универсальный, но более сложный в конфигурации способ – переключить режим работы Spring AOP с динамических прокси на нечто другое. Обычно применяется библиотека AspectJ:
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
В Spring AOP есть понятие weaving – этап добавления дополнительной функциональности (аспектов). В нашем случае, это код открытия/закрытия транзакции. Чтобы заработал weaving AspectJ этапа компиляции, в сборку нужно добавить плагин: aspectj-maven-plugin для maven, gradle-aspectj для gradle.
Подробнее об экспериментах с разными режимами Spring AOP можно почитать в статье на хабре.
👉@BookJava
Baeldung on Kotlin
Programmatic Transaction Management in Spring | Baeldung
Learn to manage transactions programmatically in Spring and why this approach is sometimes better than simply using the declarative Transactional annotation.
👍4
Двухфакторная аутентификация с помощью Spring Security
В этой статье мы рассмотрим двухфакторную аутентификацию с помощью Spring Security. Мы будем использовать soft token с Spring Security.
Добавление дополнительного уровня безопасности для вашего приложения всегда является хорошей практикой, особенно с учетом меняющейся динамики безопасности. Для некоторых приложений наличие двухфакторной аутентификации является обязательным требованием. Хотя в Spring security нет встроенной двухфакторной аутентификации, но гибкая архитектура Spring Security Architecture позволяет легко добавить эту функциональность в ваше приложение.
https://www.javadevjournal.com/spring-security/two-factor-authentication-with-spring-security/
👉@BookJava
В этой статье мы рассмотрим двухфакторную аутентификацию с помощью Spring Security. Мы будем использовать soft token с Spring Security.
Добавление дополнительного уровня безопасности для вашего приложения всегда является хорошей практикой, особенно с учетом меняющейся динамики безопасности. Для некоторых приложений наличие двухфакторной аутентификации является обязательным требованием. Хотя в Spring security нет встроенной двухфакторной аутентификации, но гибкая архитектура Spring Security Architecture позволяет легко добавить эту функциональность в ваше приложение.
https://www.javadevjournal.com/spring-security/two-factor-authentication-with-spring-security/
👉@BookJava
👍5
Шпаргалка по структурам данных в Java
К каждому собеседованию важно готовиться и проще всего это делать, когда перед глазами есть готовый материал. В данной публикации я хочу поделиться с вами своей шпаргалкой, которую использую перед собеседованиями для повторения структур данных в Java.
https://habr.com/ru/articles/751648/
👉@BookJava
К каждому собеседованию важно готовиться и проще всего это делать, когда перед глазами есть готовый материал. В данной публикации я хочу поделиться с вами своей шпаргалкой, которую использую перед собеседованиями для повторения структур данных в Java.
https://habr.com/ru/articles/751648/
👉@BookJava
Хабр
Шпаргалка по структурам данных в Java
К каждому собеседованию важно готовиться и проще всего это делать, когда перед глазами есть готовый материал. В данной публикации я хочу поделиться с вами своей шпаргалкой, которую использую перед...
👍3🥰2
Советы по Spring 💡
Создайте отказоустойчивый микросервис с помощью паттерна Circuit Breaker, используя Resilience4j. 🔥
https://resilience4j.readme.io/
👉@BookJava
Создайте отказоустойчивый микросервис с помощью паттерна Circuit Breaker, используя Resilience4j. 🔥
https://resilience4j.readme.io/
👉@BookJava
👍8
Совет по Java ☕️
В Java 22 появился новый форматированный тип `
👉@BookJava
В Java 22 появился новый форматированный тип `
ListFormat
`. Он создает или разбирает список конкатенированных строк с учетом локальных особенностей. Предусмотрено 3 типа конкатенации: STANDARD
, OR
и UNIT
, и 3 стиля для каждого типа: FULL
, SHOR
T и NARROW
.👉@BookJava
🔥7👍2👀1
Media is too big
VIEW IN TELEGRAM
Java. Префиксное дерево. Основные операции, сохранение в файл, практическое применение.
В данном видео я рассказываю о префиксных деревьях. Разбираем, что из себя представляет префиксное дерево, для чего оно применяется. Изучаем и реализуем основные операции с префиксным деревом на языке программирования Java. Кроме этого я показываю как сохранить дерево в файл и потом загрузить обратно. С помощью этого проверяю, насколько выгодней может быть хранение строк в префиксном дереве на примере автомобильных номеров.
00:00 - Вступление
00:26 - Применение в приложении
01:58 - Построение дерева и операции с ним
06:33 - Построение префиксного дерева на Java
11:22 - Операции с префиксным деревом на Java
16:31 - Сохранение дерева в файл
20:51 - Загрузка дерева из файла
25:32 - Экономия по сравнению со списком
27:12 - Замечание о Null-безопасности
28:26 - Заключение
источник
👉@BookJava
В данном видео я рассказываю о префиксных деревьях. Разбираем, что из себя представляет префиксное дерево, для чего оно применяется. Изучаем и реализуем основные операции с префиксным деревом на языке программирования Java. Кроме этого я показываю как сохранить дерево в файл и потом загрузить обратно. С помощью этого проверяю, насколько выгодней может быть хранение строк в префиксном дереве на примере автомобильных номеров.
00:00 - Вступление
00:26 - Применение в приложении
01:58 - Построение дерева и операции с ним
06:33 - Построение префиксного дерева на Java
11:22 - Операции с префиксным деревом на Java
16:31 - Сохранение дерева в файл
20:51 - Загрузка дерева из файла
25:32 - Экономия по сравнению со списком
27:12 - Замечание о Null-безопасности
28:26 - Заключение
источник
👉@BookJava
👍5
Советы по Spring 💡
Чтобы выполнять действия в транзакции базы данных, вы можете использовать шаблон Spring TransactionTemplate вместо
👉@BookJava
Чтобы выполнять действия в транзакции базы данных, вы можете использовать шаблон Spring TransactionTemplate вместо
@Transactional
👉@BookJava
👍8
В отличие от других немодульных "soft keywords" в Java (permits, sealed, yield, record, var), здесь разрешено использовать "when" в качестве имени типа, так что этот код совершенно допустим. Интересно, было ли это сознательное исключение, или на него не обратили внимания...
👉@BookJava
👉@BookJava
👍3🤮1
Совет по Java ☕️
JSON Patch и Merge Patch с Jackson
https://gist.github.com/aoudiamoncef/e2c63a69a6520866db2e12e69bb96a1b
👉@BookJava
JSON Patch и Merge Patch с Jackson
https://gist.github.com/aoudiamoncef/e2c63a69a6520866db2e12e69bb96a1b
👉@BookJava
👍3
♨️ Прокачивай свои навыки вместе с Java | Фишки и трюки
Ежедневные порции Java-фишек, полезные советы и трюки от опытных разработчиков.
👉🏼 Присоединиться
Ежедневные порции Java-фишек, полезные советы и трюки от опытных разработчиков.
👉🏼 Присоединиться
👍5🔥1
Как сгенерировать хорошее случайное число?
Этот вопрос глубже, чем кажется на первый взгляд. Для начала, нужно разобраться в двух понятиях: псевдослучайные, и истинно случайные числа.
Псевдослучайные числа – это последовательность случайных на вид чисел, на самом деле полученных в результате математического алгоритма. Последовательность таких чисел можно воспроизвести, зная начальные условия (seed, энтропия) и используемый алгоритм. Метод, который используется для генерации чисел в классе
Истинно случайные числа основываются на физических свойствах, которые трудно поддаются измерению. Это могут быть, например, доли секунд текущего системного времени. Алгоритм генерации истинно случайных чисел не позволяет с хорошей точностью угадать следующее число, даже зная предыдущие.
Класс
Не все случайные числа одинаково случайны. Шанс что рост случайного человека окажется ближе к среднему высок, тогда как у игральной кости одинакова вероятность выпадения любой из граней. В математике это называется распределением вероятностей.
Внутри
👉@BookJava
Этот вопрос глубже, чем кажется на первый взгляд. Для начала, нужно разобраться в двух понятиях: псевдослучайные, и истинно случайные числа.
Псевдослучайные числа – это последовательность случайных на вид чисел, на самом деле полученных в результате математического алгоритма. Последовательность таких чисел можно воспроизвести, зная начальные условия (seed, энтропия) и используемый алгоритм. Метод, который используется для генерации чисел в классе
java.util.Random
, дает криптографически ненадежные псевдослучайные числа – злоумышленник может достаточно легко их предугадывать.Истинно случайные числа основываются на физических свойствах, которые трудно поддаются измерению. Это могут быть, например, доли секунд текущего системного времени. Алгоритм генерации истинно случайных чисел не позволяет с хорошей точностью угадать следующее число, даже зная предыдущие.
Класс
SecureRandom
предоставляет доступ к криптографически надежным генераторам случайных чисел. При том, это могут быть как достаточно сложные последовательности псевдослучайных, так и истинно случайные числа. Согласно стандартам безопасности, они будут достаточно непредсказуемы.Не все случайные числа одинаково случайны. Шанс что рост случайного человека окажется ближе к среднему высок, тогда как у игральной кости одинакова вероятность выпадения любой из граней. В математике это называется распределением вероятностей.
Внутри
SecureRandom
использует SPI. Мы можем выбирать из различных алгоритмов генерации и их провайдеров, указав их названия в фабричном методе getInstance
. Все перечисленные выше свойства определяются именно используемым алгоритмом.👉@BookJava
👍8😁1👀1
Media is too big
VIEW IN TELEGRAM
Совет по Spring
В этом выпуске мы рассмотрим новый проект Spring Boot Testjars, который значительно упрощает создание и повторное использование сателлитных Java-сервисов, таких как микросервисы на базе Spring Boot или инфраструктура, например, Spring Authorization Server.
👉@BookJava
В этом выпуске мы рассмотрим новый проект Spring Boot Testjars, который значительно упрощает создание и повторное использование сателлитных Java-сервисов, таких как микросервисы на базе Spring Boot или инфраструктура, например, Spring Authorization Server.
👉@BookJava
👍4
MyBatis «на минималках»
В этой статье расскажу про не очень распространённый фреймворк MyBatis.
Почему MyBatis? Потому что мы в CDEK используем его в большинстве проектов, и в деле он весьма неплохо себя показал. Немного сложен и непривычен на этапе входа, но все эти минусы перекрываются его гибкостью. «Да есть Hibernate, Jooq, JDBC и еще что‑то», — скажут бывалые. Есть, но в данной статье речь пойдёт о MyBatis.
Статья будет полезна новичкам, которые хотели попробовать данный фреймворк или попробовали, но что‑то не получилось.
https://habr.com/ru/companies/cdek_blog/articles/771714/
👉@BookJava
В этой статье расскажу про не очень распространённый фреймворк MyBatis.
Почему MyBatis? Потому что мы в CDEK используем его в большинстве проектов, и в деле он весьма неплохо себя показал. Немного сложен и непривычен на этапе входа, но все эти минусы перекрываются его гибкостью. «Да есть Hibernate, Jooq, JDBC и еще что‑то», — скажут бывалые. Есть, но в данной статье речь пойдёт о MyBatis.
Статья будет полезна новичкам, которые хотели попробовать данный фреймворк или попробовали, но что‑то не получилось.
https://habr.com/ru/companies/cdek_blog/articles/771714/
👉@BookJava
👍3
В чем различие между приватным конструктором и финальным классом?
Ограничение области видимости конструктора до private не дает вызвать его из наследника, что приводит к невозможности наследоваться. Это свойство часто используется для утилитарных классов и синглтонов. Если применить порождающий паттерн, то можно вернуть возможность инстанцирования извне.
Если добавить объявлению класса модификатор final, это также запретит от него наследоваться, уже без излишнего ограничения на использование конструктора снаружи. Это основное применение этих двух подходов.
С точки зрения возможности наследования, ограничение через private конструктор более слабое. От такого класса, если он не финальный, можно наследовать внутренние и вложенные подклассы. Публичный вложенный класс может сработать как «паблик морозов» – дать внешним классам наследоваться через себя.
👉@BookJava
Ограничение области видимости конструктора до private не дает вызвать его из наследника, что приводит к невозможности наследоваться. Это свойство часто используется для утилитарных классов и синглтонов. Если применить порождающий паттерн, то можно вернуть возможность инстанцирования извне.
Если добавить объявлению класса модификатор final, это также запретит от него наследоваться, уже без излишнего ограничения на использование конструктора снаружи. Это основное применение этих двух подходов.
С точки зрения возможности наследования, ограничение через private конструктор более слабое. От такого класса, если он не финальный, можно наследовать внутренние и вложенные подклассы. Публичный вложенный класс может сработать как «паблик морозов» – дать внешним классам наследоваться через себя.
class NonInheritable {
private NonInheritable() {}
public static class PublicMorozov extends NonInheritable {}
}
class SubClass extends NonInheritable. PublicMorozov {
//
Технически, это наследник NonInheritable. Никакой ошибки!👉@BookJava
👍6❤1
Зачем нужны и какие бывают блоки инициализации?
Блоки инициализации представляют собой код, заключенный в фигурные скобки и размещаемый внутри класса вне объявления методов или конструкторов.
• Существуют статические и нестатические блоки инициализации.
• Блок инициализации выполняется перед инициализацией класса загрузчиком классов или созданием объекта класса с помощью конструктора.
• Несколько блоков инициализации выполняются в порядке следования в коде класса.
• Блок инициализации способен генерировать исключения, если их объявления перечислены в throws всех конструкторов класса.
• Блок инициализации возможно создать и в анонимном классе.
👉@BookJava
Блоки инициализации представляют собой код, заключенный в фигурные скобки и размещаемый внутри класса вне объявления методов или конструкторов.
• Существуют статические и нестатические блоки инициализации.
• Блок инициализации выполняется перед инициализацией класса загрузчиком классов или созданием объекта класса с помощью конструктора.
• Несколько блоков инициализации выполняются в порядке следования в коде класса.
• Блок инициализации способен генерировать исключения, если их объявления перечислены в throws всех конструкторов класса.
• Блок инициализации возможно создать и в анонимном классе.
👉@BookJava
❤6👍2