2. Кэширование ключей
Создание и парсинг ключей (особенно для асимметричных алгоритмов, таких как RSA) — дорогостоящая операция с точки зрения CPU и памяти.
Например:
Генерация RSA-ключей требует значительных вычислительных ресурсов.
Повторное декодирование Base64-строк для ключей при каждом запросе увеличивает нагрузку.
Рекомендации:
Кэшируйте ключи в памяти (например, в ConcurrentHashMap или с использованием Spring Cache).
Используйте пул ключей для многопоточных приложений, чтобы избежать создания новых экземпляров Key для каждого запроса.
Пример кэширования ключа:
3. Многопоточность
Библиотека jjwt потокобезопасна, но неправильное управление ключами или токенами может привести к проблемам.
Например:
Неправильное использование ThreadLocal для хранения временных ключей может привести к утечкам памяти.
Частое создание JwtParser без повторного использования увеличивает потребление ресурсов.
Рекомендации:
Создавайте и конфигурируйте JwtParserBuilder один раз и переиспользуйте его.
Используйте ThreadLocal только для временных данных, которые очищаются после обработки запроса.
Пример потокобезопасного парсера:
Нюансы безопасности
1. Выбор алгоритма подписи
HMAC-SHA (HS256, HS384, HS512): Быстрее, но требует безопасного хранения секретного ключа на всех серверах. Утечка ключа компрометирует всю систему.
RSA/ECDSA: Медленнее, но безопаснее, так как публичный ключ используется для проверки, а приватный хранится только на сервере, выдающем токены.
None-алгоритм: Никогда не используйте alg: none, так как это позволяет подделывать токены без подписи.
Рекомендации:
Для микросервисов с централизованным управлением ключами предпочтительнее RSA/ECDSA.
Используйте jjwt с настройкой require("alg"), чтобы предотвратить атаки с изменением алгоритма:
2. Срок действия токена
Короткий срок действия (exp) снижает риск использования украденных токенов, но увеличивает нагрузку на сервер из-за частого обновления токенов (refresh tokens).
Рекомендации:
Устанавливайте exp в пределах 15-60 минут для access-токенов.
Используйте refresh-токены с более длинным сроком действия и строгим контролем (например, храните их в базе данных с возможностью отзыва).
3. Уязвимости
JWT Header Injection: Атакующий может изменить заголовок, чтобы подменить алгоритм (например, с RS256 на HS256). Всегда проверяйте алгоритм при парсинге.
Weak Keys: Слабые или предсказуемые ключи для HMAC-SHA делают токены уязвимыми для brute-force атак.
Payload Tampering: Если токен не подписан или подпись не проверяется, злоумышленник может изменить payload.
Рекомендации:
Используйте ключи достаточной длины (например, 256 бит для HS256).
Проверяйте подпись токена на каждом запросе.
Включайте jti (JWT ID) для отслеживания и отзыва токенов.
#Java #middle #on_request #Jwt
Создание и парсинг ключей (особенно для асимметричных алгоритмов, таких как RSA) — дорогостоящая операция с точки зрения CPU и памяти.
Например:
Генерация RSA-ключей требует значительных вычислительных ресурсов.
Повторное декодирование Base64-строк для ключей при каждом запросе увеличивает нагрузку.
Рекомендации:
Кэшируйте ключи в памяти (например, в ConcurrentHashMap или с использованием Spring Cache).
Используйте пул ключей для многопоточных приложений, чтобы избежать создания новых экземпляров Key для каждого запроса.
Пример кэширования ключа:
private static final Key SIGNING_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
public static String createJwt(String subject, long ttlMillis) {
return Jwts.builder()
.setSubject(subject)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + ttlMillis))
.signWith(SIGNING_KEY)
.compact();
}
3. Многопоточность
Библиотека jjwt потокобезопасна, но неправильное управление ключами или токенами может привести к проблемам.
Например:
Неправильное использование ThreadLocal для хранения временных ключей может привести к утечкам памяти.
Частое создание JwtParser без повторного использования увеличивает потребление ресурсов.
Рекомендации:
Создавайте и конфигурируйте JwtParserBuilder один раз и переиспользуйте его.
Используйте ThreadLocal только для временных данных, которые очищаются после обработки запроса.
Пример потокобезопасного парсера:
private static final JwtParser JWT_PARSER = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor("secret".getBytes()))
.build();
public static Claims parseJwt(String jwt) {
return JWT_PARSER.parseClaimsJws(jwt).getBody();
}
Нюансы безопасности
1. Выбор алгоритма подписи
HMAC-SHA (HS256, HS384, HS512): Быстрее, но требует безопасного хранения секретного ключа на всех серверах. Утечка ключа компрометирует всю систему.
RSA/ECDSA: Медленнее, но безопаснее, так как публичный ключ используется для проверки, а приватный хранится только на сервере, выдающем токены.
None-алгоритм: Никогда не используйте alg: none, так как это позволяет подделывать токены без подписи.
Рекомендации:
Для микросервисов с централизованным управлением ключами предпочтительнее RSA/ECDSA.
Используйте jjwt с настройкой require("alg"), чтобы предотвратить атаки с изменением алгоритма:
Jwts.parserBuilder()
.require("alg", "RS256")
.setSigningKey(publicKey)
.build();
2. Срок действия токена
Короткий срок действия (exp) снижает риск использования украденных токенов, но увеличивает нагрузку на сервер из-за частого обновления токенов (refresh tokens).
Рекомендации:
Устанавливайте exp в пределах 15-60 минут для access-токенов.
Используйте refresh-токены с более длинным сроком действия и строгим контролем (например, храните их в базе данных с возможностью отзыва).
3. Уязвимости
JWT Header Injection: Атакующий может изменить заголовок, чтобы подменить алгоритм (например, с RS256 на HS256). Всегда проверяйте алгоритм при парсинге.
Weak Keys: Слабые или предсказуемые ключи для HMAC-SHA делают токены уязвимыми для brute-force атак.
Payload Tampering: Если токен не подписан или подпись не проверяется, злоумышленник может изменить payload.
Рекомендации:
Используйте ключи достаточной длины (например, 256 бит для HS256).
Проверяйте подпись токена на каждом запросе.
Включайте jti (JWT ID) для отслеживания и отзыва токенов.
#Java #middle #on_request #Jwt
👍4
Оптимизация и масштабирование
1. Хранение и ротация ключей
Для HMAC-SHA ключи должны безопасно храниться (например, в Vault или AWS KMS).
Для RSA/ECDSA используйте ротацию ключей с поддержкой JWK (JSON Web Key) для автоматического обновления публичных ключей.
2. Масштабирование в микросервисах
Централизуйте выдачу токенов через отдельный сервис (например, Auth Service).
Используйте JWK для распространения публичных ключей между сервисами.
3. Кэширование токенов
Кэшируйте проверенные токены в Redis или другом in-memory хранилище, чтобы снизить нагрузку на парсинг и валидацию.
Используйте TTL кэша, соответствующий exp токена.
4. Логирование и мониторинг
Логируйте попытки использования невалидных или истекших токенов для анализа атак.
Мониторьте время парсинга и валидации токенов, чтобы выявить узкие места.
Пример интеграции с Spring Security
JWT часто используется в связке с Spring Security для защиты REST API.
Пример конфигурации:
#Java #middle #on_request #Jwt
1. Хранение и ротация ключей
Для HMAC-SHA ключи должны безопасно храниться (например, в Vault или AWS KMS).
Для RSA/ECDSA используйте ротацию ключей с поддержкой JWK (JSON Web Key) для автоматического обновления публичных ключей.
2. Масштабирование в микросервисах
Централизуйте выдачу токенов через отдельный сервис (например, Auth Service).
Используйте JWK для распространения публичных ключей между сервисами.
3. Кэширование токенов
Кэшируйте проверенные токены в Redis или другом in-memory хранилище, чтобы снизить нагрузку на парсинг и валидацию.
Используйте TTL кэша, соответствующий exp токена.
4. Логирование и мониторинг
Логируйте попытки использования невалидных или истекших токенов для анализа атак.
Мониторьте время парсинга и валидации токенов, чтобы выявить узкие места.
Пример интеграции с Spring Security
JWT часто используется в связке с Spring Security для защиты REST API.
Пример конфигурации:
import io.jsonwebtoken.Jwts;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
try {
Claims claims = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor("secret".getBytes()))
.build()
.parseClaimsJws(token)
.getBody();
String username = claims.getSubject();
if (username != null) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
username, null, Collections.emptyList());
SecurityContextHolder.getContext().setAuthentication(auth);
}
} catch (Exception e) {
SecurityContextHolder.clearContext();
}
}
chain.doFilter(request, response);
}
}
#Java #middle #on_request #Jwt
👍4
Вячеслав Васильевич Петров (3 августа 1940, г. Лиски, Воронежская область, РСФСР, СССР).
Советский учёный в области информационных технологий и оптоэлектронных систем хранения информации, академик НАН Украины, директор Института проблем регистрации информации НАН Украины. Разработал основы оптических запоминающих устройств большой ёмкости и участвовал в координации национальных программ информатизации.
Эдвард Делано Лазовска (Edward Delano Lazowska) – родился 3 августа 1950 года.
Американский учёный в области информатики, профессор Вашингтонского университета, внёс значительный вклад в теорию и практику высокопроизводительных вычислений и систем связи. Соавтор фундаментального учебника по анализу производительности компьютерных систем и участник разработки методов эффективного управления ресурсами в многопроцессорных и сетевых средах.
Дханурджей «DJ» Патил (Dhanurjay Patil) – родился 3 августа 1974 года.
Американский математик и специалист по компьютерным наукам, с 2015 по 2017 год первый Chief Data Scientist США (советник Белого дома по наукам о данных). Известен как один из пионеров «науки о данных» (data science), разрабатывал методики анализа больших данных для государственной политики и коммерческих проектов.
#Biography #Birth_Date
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Сломай свой хаос 😵💫
Ты начал работать на удалёнке.
Никто не говорит тебе, когда начинать.
Хочешь — работай днём, хочешь — ночью. Важен только результат.
Звучит как мечта, да?
На самом деле — это ловушка.
Потому что без самоорганизации ты быстро превратишься в зомби, который "делает вид, что работает", а внутри тонет в хаосе.
🤫 Самообучение смертельно опасно, если заниматься этим беспорядочно
Курсы, видео, статьи, pet-проекты.
Сотни вкладок, 5 начатых репозиториев, ни одного завершённого.
Кажется, что ты в процессе… но на самом деле ты в болоте.
В психологии это состояние называют cognitive overload — когнитивная перегрузка.
(Sweller, J., Ayres, P., & Kalyuga, S. (2011). Cognitive Load Theory)
Ты берёшь на себя больше информации, чем способен обработать, и эффективность падает до нуля.
В IT это смертельно. Технологии бегут вперёд, а ты всё ещё бродишь по курсу «Java для начинающих» третий месяц без прогресса.
😞 Почему хаос убивает продуктивность
Нет границ
Удалёнка или самообучение = никто не скажет «стоп». В итоге либо работаешь до трёх ночи, либо растягиваешь одну задачу на весь день.
Потеря приоритетов
Вместо реальных задач ковыряешь шрифты в IDE, читаешь про новый фреймворк "на всякий случай". Это называется procrastination through busyness — прокрастинация через псевдозанятость.
(Pychyl, T. A., & Sirois, F. M. (2013). Procrastination, emotion regulation, and well-being)
Отсутствие ритма
Мозг — не хаотичная машина. Ему нужны циклы активности и отдыха (circadian rhythm). Без них ты превращаешься в сонного, раздражённого, медленного кодера.
‼️ Что же делать ‼️
😑 Разбивай путь на малые шаги. Строй планы, декомпозируй их на малые таски и стремись их выполнить.
И четко придерживайся плана. Чем точнее ты выполнишь задачу, уложившись в отведенное время, тем проще будет следующая.
Декомпозиция и обязательность - тоже навыки. Их тоже можно прокачать. Не пренебрегай ими.
🤨 Стань себе начальником. Заставь себя. Выстрели в свою лень.
Ставь задачи в календарь с точным временем.
Не что-то в голове, на уровне идей, а конкретика: в 19:00–20:30 — пишу код для pet-проекта.
И это время не двигается. Совсем.
😏 Одна задача = один фокус. Концентрация прокачивается. Строй вокруг себя условия, чтобы она не сбивалась.
Single-tasking — продуктивность падает, если переключаться между задачами.
Закрываешь IDE, чтобы на секундочку проверить почту - потерял 20–30% концентрации.
Делай одно дело за раз.
😐 Убери "проблему первого шага".
Хочешь учиться?
Сделай так, чтобы:
IDE уже была открыта
Курс уже загружен
Репозиторий уже клонирован
Это называется reducing activation energy — чем меньше действий до старта, тем выше шанс, что ты реально начнёшь.
(Oettingen, G., & Gollwitzer, P. M. (2010). Strategies of setting and implementing goals: Mental contrasting and implementation intentions. In Social Psychological Foundations of Clinical Psychology)
🤔 Почему это важно для айтишника
В офисе тебя могут спасать менеджеры, график, коллеги, которые напоминают о дедлайнах.
На удалёнке или при самообучении у тебя есть только Ты.
И если ты сам себе не начальник — значит, ты сам себе враг.
Самоорганизация — это не про мотивацию, а про систему. Мотивация придет позже.
Система = привычки, которые работают даже в дни, когда ты не хочешь работать.
Если не начнёшь ломать хаос сегодня — завтра он сломает тебя.
Поэтому, запланируй ответить мне в комментариях, что ты думаешь об это статье! Прокачай навык😉
Понравилась статья - поделись с другом, позови его на канал и будет тебе моя благодарность 🤝
😎
#motivation
Ты начал работать на удалёнке.
Никто не говорит тебе, когда начинать.
Хочешь — работай днём, хочешь — ночью. Важен только результат.
Звучит как мечта, да?
На самом деле — это ловушка.
Потому что без самоорганизации ты быстро превратишься в зомби, который "делает вид, что работает", а внутри тонет в хаосе.
"Можно быть умным, талантливым, даже иметь опыт.
Но без умения строить свой день и держать ритм — в долгую ты не вытянешь."
Курсы, видео, статьи, pet-проекты.
Сотни вкладок, 5 начатых репозиториев, ни одного завершённого.
Кажется, что ты в процессе… но на самом деле ты в болоте.
В психологии это состояние называют cognitive overload — когнитивная перегрузка.
(Sweller, J., Ayres, P., & Kalyuga, S. (2011). Cognitive Load Theory)
Ты берёшь на себя больше информации, чем способен обработать, и эффективность падает до нуля.
В IT это смертельно. Технологии бегут вперёд, а ты всё ещё бродишь по курсу «Java для начинающих» третий месяц без прогресса.
Нет границ
Удалёнка или самообучение = никто не скажет «стоп». В итоге либо работаешь до трёх ночи, либо растягиваешь одну задачу на весь день.
Потеря приоритетов
Вместо реальных задач ковыряешь шрифты в IDE, читаешь про новый фреймворк "на всякий случай". Это называется procrastination through busyness — прокрастинация через псевдозанятость.
(Pychyl, T. A., & Sirois, F. M. (2013). Procrastination, emotion regulation, and well-being)
Отсутствие ритма
Мозг — не хаотичная машина. Ему нужны циклы активности и отдыха (circadian rhythm). Без них ты превращаешься в сонного, раздражённого, медленного кодера.
И четко придерживайся плана. Чем точнее ты выполнишь задачу, уложившись в отведенное время, тем проще будет следующая.
Декомпозиция и обязательность - тоже навыки. Их тоже можно прокачать. Не пренебрегай ими.
Ставь задачи в календарь с точным временем.
Не что-то в голове, на уровне идей, а конкретика: в 19:00–20:30 — пишу код для pet-проекта.
И это время не двигается. Совсем.
Single-tasking — продуктивность падает, если переключаться между задачами.
Закрываешь IDE, чтобы на секундочку проверить почту - потерял 20–30% концентрации.
Делай одно дело за раз.
Хочешь учиться?
Сделай так, чтобы:
IDE уже была открыта
Курс уже загружен
Репозиторий уже клонирован
Это называется reducing activation energy — чем меньше действий до старта, тем выше шанс, что ты реально начнёшь.
(Oettingen, G., & Gollwitzer, P. M. (2010). Strategies of setting and implementing goals: Mental contrasting and implementation intentions. In Social Psychological Foundations of Clinical Psychology)
В офисе тебя могут спасать менеджеры, график, коллеги, которые напоминают о дедлайнах.
На удалёнке или при самообучении у тебя есть только Ты.
И если ты сам себе не начальник — значит, ты сам себе враг.
Самоорганизация — это не про мотивацию, а про систему. Мотивация придет позже.
Система = привычки, которые работают даже в дни, когда ты не хочешь работать.
Если не начнёшь ломать хаос сегодня — завтра он сломает тебя.
Поэтому, запланируй ответить мне в комментариях, что ты думаешь об это статье! Прокачай навык
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3 1
Генна́дий Фёдорович Филаре́тов (род. 4 августа 1938, Москва).
Советский и российский учёный в области вычислительной техники, специалист по цифровому анализу сигналов и нейросетям, участвовал в разработке систем автоматики и информационных технологий.
Пётр Дми́триевич Зе́гжда (4 августа 1940, Соликамск — 12 февраля 2022, Санкт-Петербург).
Российский учёный и профессор СПбПУ, один из основателей учебной кафедры «Информационная безопасность компьютерных систем», разработчик методов и систем защиты информации.
Фрэнсис Элизабет Аллен (англ. Frances Elizabeth Allen; 4 августа 1932 года, штат Нью-Йорк — 4 августа 2020).
Американский учёный в области теории вычислительных систем, первая женщина – лауреат премии Тьюринга (2006).
#Biography #Birth_Date
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Модульность и многомодульные проекты в Gradle
Gradle поддерживает многомодульные проекты, позволяя организовать проект в виде иерархии подмодулей, каждый из которых имеет собственный build.gradle или build.gradle.kts. Это обеспечивает модульность, разделение ответственности и повторное использование кода.
Преимущества:
Разделение функциональности на независимые модули (например, API, ядро, реализация).
Упрощение тестирования и поддержки.
Параллельная сборка модулей для повышения производительности.
Повторное использование конфигураций и зависимостей.
settings.gradle(.kts) — управление include-проектами
Файл settings.gradle (или settings.gradle.kts) определяет структуру многомодульного проекта, включая корневое имя и подмодули.
Основные функции:
Указание имени корневого проекта: rootProject.name.
Включение подмодулей через include.
Настройка репозиториев и плагинов через pluginManagement.
Пример (Groovy DSL):
Kotlin DSL:
Нюансы:
Структура multi-module проекта: Parent + Children
Многомодульный проект состоит из корневого (parent) проекта и подмодулей (children), каждый из которых имеет собственный build.gradle.
Пример структуры:
Parent проект:
Корневой build.gradle задает общие настройки, плагины и зависимости для всех подмодулей.
Пример:
Children проекты:
Каждый подмодуль имеет собственный build.gradle, определяющий специфические задачи, зависимости и конфигурации.
Пример (module-api/build.gradle):
В памяти: Корневой проект загружает модель для всех подмодулей, включая их задачи и зависимости. Каждый подмодуль добавляет объект Project и граф задач, увеличивая потребление памяти.
Для оптимизации используйте --configure-on-demand:
Project Access: project(":module")
Подмодули доступны через объект project с использованием их пути, определенного в settings.gradle.
Пример:
Это добавляет module-core как зависимость для текущего модуля.
Нюансы:
Путь начинается с : для корневого проекта (например, :module-core:submodule для вложенных модулей).
Доступ к свойствам другого модуля:println project(':module-core').version
#Java #middle #Gradle #Task #include_projects
Gradle поддерживает многомодульные проекты, позволяя организовать проект в виде иерархии подмодулей, каждый из которых имеет собственный build.gradle или build.gradle.kts. Это обеспечивает модульность, разделение ответственности и повторное использование кода.
Преимущества:
Разделение функциональности на независимые модули (например, API, ядро, реализация).
Упрощение тестирования и поддержки.
Параллельная сборка модулей для повышения производительности.
Повторное использование конфигураций и зависимостей.
В памяти: Каждый модуль создает собственный объект Project в модели Gradle, увеличивая потребление памяти пропорционально количеству модулей (обычно 50-100 МБ на модуль). Граф задач (DAG) для всех модулей хранится в памяти, что может достигать 1-2 ГБ для крупных проектов.
settings.gradle(.kts) — управление include-проектами
Файл settings.gradle (или settings.gradle.kts) определяет структуру многомодульного проекта, включая корневое имя и подмодули.
Основные функции:
Указание имени корневого проекта: rootProject.name.
Включение подмодулей через include.
Настройка репозиториев и плагинов через pluginManagement.
Пример (Groovy DSL):
rootProject.name = 'my-project'
include 'module-api', 'module-core', 'module-web'
Kotlin DSL:
rootProject.name = "my-project"
include("module-api", "module-core", "module-web")
Нюансы:
Каждый подмодуль должен иметь собственный build.gradle в папке с таким же именем (например, module-api/build.gradle).
Подмодули могут быть вложенными:include 'module-core:submodule'
В памяти: settings.gradle загружается на фазе инициализации, создавая модель проекта с объектами Project для каждого модуля. Это минимальная фаза по потреблению памяти (50-100 МБ), но сложные настройки (например, pluginManagement) могут увеличить overhead.
Структура multi-module проекта: Parent + Children
Многомодульный проект состоит из корневого (parent) проекта и подмодулей (children), каждый из которых имеет собственный build.gradle.
Пример структуры:
my-project/
├── build.gradle
├── settings.gradle
├── module-api/
│ └── build.gradle
├── module-core/
│ └── build.gradle
├── module-web/
│ └── build.gradle
Parent проект:
Корневой build.gradle задает общие настройки, плагины и зависимости для всех подмодулей.
Пример:
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'java'
dependencies {
testImplementation 'junit:junit:4.13.2'
}
}
Children проекты:
Каждый подмодуль имеет собственный build.gradle, определяющий специфические задачи, зависимости и конфигурации.
Пример (module-api/build.gradle):
plugins {
id 'java-library'
}
dependencies {
api 'org.apache.commons:commons-lang3:3.12.0'
}
В памяти: Корневой проект загружает модель для всех подмодулей, включая их задачи и зависимости. Каждый подмодуль добавляет объект Project и граф задач, увеличивая потребление памяти.
Для оптимизации используйте --configure-on-demand:
./gradlew build --configure-on-demand
Project Access: project(":module")
Подмодули доступны через объект project с использованием их пути, определенного в settings.gradle.
Пример:
dependencies {
implementation project(':module-core')
}
Это добавляет module-core как зависимость для текущего модуля.
Нюансы:
Путь начинается с : для корневого проекта (например, :module-core:submodule для вложенных модулей).
Доступ к свойствам другого модуля:println project(':module-core').version
В памяти: Gradle хранит все объекты Project в памяти, обеспечивая доступ через project(). Это увеличивает модель проекта, особенно для больших иерархий модулей.
#Java #middle #Gradle #Task #include_projects
👍2
Sharing Logic между проектами
Совместное использование логики между модулями повышает повторное использование кода и упрощает поддержку.
Common Logic
В корневом build.gradle:
Используйте блоки allprojects и subprojects для общих настроек:
Скриптовые плагины:
Создайте файл common.gradle:
Подключите в подмодулях:
Кастомные плагины:
Создайте плагин для общей логики (см. раздел "Создание собственных плагинов" в предыдущей статье).
Пример применения:
Version Catalogs (libs.versions.toml)
Version Catalogs — это централизованный способ управления версиями зависимостей и плагинов, введенный в Gradle 7.0.
Настройка (gradle/libs.versions.toml):
Использование:
Kotlin DSL:
Преимущества:
Централизованное управление версиями.
Улучшенная читаемость и автодополнение в IDE.
Упрощение обновления версий.
#Java #middle #Gradle #Task #include_projects
Совместное использование логики между модулями повышает повторное использование кода и упрощает поддержку.
Common Logic
В корневом build.gradle:
Используйте блоки allprojects и subprojects для общих настроек:
subprojects {
apply plugin: 'java'
version = '1.0.0'
repositories {
mavenCentral()
}
}
Скриптовые плагины:
Создайте файл common.gradle:
apply plugin: 'java'
dependencies {
testImplementation 'junit:junit:4.13.2'
}
Подключите в подмодулях:
apply from: "$rootDir/gradle/common.gradle"
Кастомные плагины:
Создайте плагин для общей логики (см. раздел "Создание собственных плагинов" в предыдущей статье).
Пример применения:
subprojects {
apply plugin: 'com.example.common-plugin'
}
В памяти: Общая логика уменьшает дублирование кода, но увеличивает сложность модели проекта, так как Gradle загружает и парсит дополнительные скрипты или плагины.
Version Catalogs (libs.versions.toml)
Version Catalogs — это централизованный способ управления версиями зависимостей и плагинов, введенный в Gradle 7.0.
Настройка (gradle/libs.versions.toml):
[versions]
spring-boot = "2.7.18"
junit = "4.13.2"
[libraries]
spring-core = { group = "org.springframework", name = "spring-core", version.ref = "spring-boot" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
[plugins]
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
Использование:
plugins {
alias(libs.plugins.spring.boot)
}
dependencies {
implementation libs.spring.core
testImplementation libs.junit
}
Kotlin DSL:
plugins {
alias(libs.plugins.spring.boot)
}
dependencies {
implementation(libs.spring.core)
testImplementation(libs.junit)
}
Преимущества:
Централизованное управление версиями.
Улучшенная читаемость и автодополнение в IDE.
Упрощение обновления версий.
В памяти: Version Catalog загружается как часть модели проекта, добавляя минимальный overhead (10-20 МБ), но упрощает управление зависимостями, снижая вероятность конфликтов.
#Java #middle #Gradle #Task #include_projects
👍2
Сценарии и практики разделения: Core/Api/Impl
Разделение проекта на модули (Core, Api, Impl) — распространенная практика в корпоративной разработке для обеспечения модульности и повторного использования.
Core:
Содержит общую бизнес-логику, утилиты, модели данных.
Пример:
Api:
Определяет публичные интерфейсы, DTO или контракты.
Пример:
Impl:
Реализует интерфейсы из Api, добавляя конкретную функциональность.
Пример: module-impl/build.gradle:
Структура:
Практики:
Используйте api в модуле module-api для экспорта публичных интерфейсов.
Минимизируйте зависимости между модулями, чтобы избежать циклических зависимостей.
Централизуйте версии через Version Catalog или dependencyManagement в корневом build.gradle.
Gradle Composite Builds
Composite Builds позволяют включать другие Gradle-проекты как зависимости, без необходимости публикации в репозиторий.
Настройка:
В settings.gradle корневого проекта:
В build.gradle используйте проект как зависимость:
Использование:
Полезно для разработки связанных проектов, находящихся в разных репозиториях.
Gradle автоматически разрешает зависимости между проектами.
Процесс сборки с помощью task-graph (Task Avoidance, Parallel Build)
Gradle строит граф задач (Directed Acyclic Graph, DAG) для определения порядка выполнения задач в многомодульных проектах.
Task Avoidance:
Gradle использует инкрементальную сборку, пропуская задачи, чьи входные/выходные данные не изменились (up-to-date checks).
Пример:
Parallel Build:
Gradle поддерживает параллельное выполнение задач с флагом --parallel:
#Java #middle #Gradle #Task #include_projects
Разделение проекта на модули (Core, Api, Impl) — распространенная практика в корпоративной разработке для обеспечения модульности и повторного использования.
Core:
Содержит общую бизнес-логику, утилиты, модели данных.
Пример:
module-core/build.gradle:plugins {
id 'java-library'
}
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
Api:
Определяет публичные интерфейсы, DTO или контракты.
Пример:
module-api/build.gradle:plugins {
id 'java-library'
}
dependencies {
api project(':module-core')
}
Impl:
Реализует интерфейсы из Api, добавляя конкретную функциональность.
Пример: module-impl/build.gradle:
plugins {
id 'java'
}
dependencies {
implementation project(':module-api')
}
Структура:
my-project/
├── module-core/
│ └── build.gradle
├── module-api/
│ └── build.gradle
├── module-impl/
│ └── build.gradle
├── build.gradle
├── settings.gradle
Практики:
Используйте api в модуле module-api для экспорта публичных интерфейсов.
Минимизируйте зависимости между модулями, чтобы избежать циклических зависимостей.
Централизуйте версии через Version Catalog или dependencyManagement в корневом build.gradle.
В памяти: Каждый модуль добавляет объект Project, задачи и зависимости в модель Gradle, увеличивая потребление памяти. Разделение на Core/Api/Impl уменьшает размер каждого модуля, но увеличивает общее количество объектов в памяти.
Gradle Composite Builds
Composite Builds позволяют включать другие Gradle-проекты как зависимости, без необходимости публикации в репозиторий.
Настройка:
В settings.gradle корневого проекта:
includeBuild '../other-project'
В build.gradle используйте проект как зависимость:
dependencies {
implementation project(':other-project:module-x')
}
Использование:
Полезно для разработки связанных проектов, находящихся в разных репозиториях.
Gradle автоматически разрешает зависимости между проектами.
В памяти: Composite Builds загружают модели всех включенных проектов в память, значительно увеличивая overhead (100-500 МБ на проект). Используйте с осторожностью для крупных систем.
Процесс сборки с помощью task-graph (Task Avoidance, Parallel Build)
Gradle строит граф задач (Directed Acyclic Graph, DAG) для определения порядка выполнения задач в многомодульных проектах.
Task Avoidance:
Gradle использует инкрементальную сборку, пропуская задачи, чьи входные/выходные данные не изменились (up-to-date checks).
Пример:
tasks.named('compileJava') {
inputs.files('src/main/java')
outputs.dir('build/classes/java/main')
}
В памяти: Gradle хранит хэши входов/выходов в памяти и ~/.gradle/caches, добавляя небольшой overhead (10-50 МБ).
Parallel Build:
Gradle поддерживает параллельное выполнение задач с флагом --parallel:
./gradlew build --parallel
#Java #middle #Gradle #Task #include_projects
👍2
Что выведет код?
#Tasks
import java.util.BitSet;
public class Task040825 {
public static void main(String[] args) {
BitSet bs1 = new BitSet();
bs1.set(65);
BitSet bs2 = new BitSet();
bs2.set(64);
bs1.and(bs2);
System.out.println(bs1.cardinality());
}
}
#Tasks
👍2