Библиотека Java разработчика
前往频道在 Telegram
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP
显示更多📈 Telegram 频道 Библиотека Java разработчика 的分析概览
频道 Библиотека Java разработчика (@bookjava) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 10 005 名订阅者,在 技术与应用 类别中位列第 12 110,并在 俄罗斯 地区排名第 63 455 位。
📊 受众指标与增长动态
自 невідомо 创建以来,项目保持高速增长,吸引了 10 005 名订阅者。
根据 25 十月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -54,过去 24 小时变化为 -2,整体触达仍然可观。
- 认证状态: 未认证
- 互动率 (ER): 平均受众互动率为 7.79%。内容发布后 24 小时内通常能获得 3.74% 的反应,占订阅者总量。
- 帖子覆盖: 每篇帖子平均可获得 780 次浏览,首日通常累积 374 次浏览。
- 互动与反馈: 受众积极参与,单帖平均反应数为 4。
- 主题关注点: 内容集中在 string, интерфейс, строка, boot, api 等核心主题上。
📝 描述与内容策略
作者将该频道定位为表达主观观点的平台:
“📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.
По всем вопросам @evgenycarter
РКН clck.ru/3KoGeP”
凭借高频更新(最新数据采集于 26 十月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。
10 005
订阅者
-224 小时
-97 天
-5430 天
帖子存档
🚀 Подборка полезных IT каналов в Max
Системное администрирование, DevOps 📌
https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин
https://max.ru/channel_win_sysadmin Системный Администратор Windows
https://max.ru/channel_linux_admin Linux: Системный администратор
https://max.ru/channel_linuxmod Linux
https://max.ru/channel_i_linux Системный администратор
https://max.ru/channel_devopslib DevOps, SRE, Sysadmin
https://max.ru/channel_devops_star DevOps Star (Звезда Девопса)
Excel лайфхак 📌
https://t.me/Excel_lifehack Excel лайфхак
Английский с нуля 🇬🇧
https://max.ru/UchuEnglish
1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://max.ru/channel_DevLab1C 1С:Предприятие 8
Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика
https://max.ru/channel_cpp_geek C++ geek
Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика
Программирование React📌
https://max.ru/react_lib React
Программирование Rust📌
https://max.ru/channel_rust_lib
Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика
Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика
https://max.ru/channel_java_geek Java Geek
GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных
Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков
Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов
Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼💻👩💻
Шутки программистов 📌
https://max.ru/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free
Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров
Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике
Вакансии в IT📌
https://max.ru/progjob
https://max.ru/channel_rabotait
Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных
Городские📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
https://max.ru/channel_krasnodar_novosty Краснодар Новости
https://max.ru/channel_novosibirsk_novosti Новосибирск
https://max.ru/channel_samara_novosti Новости Самары
https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга
https://max.ru/channel_kazan_novosti Новости Казани
https://max.ru/channel_omsk_novosti Новости Омска
https://max.ru/channel_moskva_24 Москва 24
В Java instance initializer blocks (блоки инициализации экземпляра) выполняются в следующем порядке:
- Они выполняются каждый раз, когда создается новый объект класса.
- Выполнение происходит после вызова конструктора родительского класса (
super()), но до тела конструктора текущего класса.
Порядок инициализации:
1. Сначала инициализируются поля в порядке их объявления.
2. Затем выполняются instance initializer blocks, в том порядке, в котором они написаны в коде.
3. После этого выполняется тело конструктора.
Пример:
class Example {
int x = 10;
{
System.out.println("Instance initializer block");
x = 20;
}
Example() {
System.out.println("Constructor");
System.out.println("x = " + x);
}
public static void main(String[] args) {
Example ex = new Example();
}
}
Вывод:
Instance initializer block Constructor x = 20Ключевые моменты: - Статические блоки (
static {}) — другое дело: они выполняются один раз при загрузке класса.
- Instance initializer blocks полезны для общей инициализации, которую нужно выполнять вне зависимости от того, какой конструктор вызывается.
📲 Мы в MAX
👉@BookJava🔴 Завтра тестовое собеседование с Java-разработчиком
5 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
🧠 Сегодня покажу вам полезный трюк для Spring Boot: как элегантно валидировать параметры контроллера без лишнего кода.
Часто вижу, как в контроллерах вручную проверяют
@RequestParam на пустоту или формат. Это шумит код и приводит к ошибкам.
Вместо этого используйте аннотации валидации прямо на параметрах:
@RestController
@RequestMapping("/api")
@Validated // Обязательно!
public class UserController {
@GetMapping("/users")
public List<User> getUsers(
@RequestParam @NotBlank String name,
@RequestParam @Min(18) int age
) {
// Если валидация не пройдена — автоматически вернётся 400 Bad Request
return userService.findUsers(name, age);
}
}
📌 Ключевые моменты:
- Обязательно ставим @Validated над классом контроллера.
- На параметры добавляем любые стандартные аннотации из jakarta.validation.constraints.
- Ошибки валидации Spring обработает автоматически через MethodArgumentNotValidException.
💡 Можно кастомизировать ответ на ошибку, добавив глобальный @ExceptionHandler.
⚠️ Без @Validated аннотации на контроллере валидация параметров работать не будет!
📲 Мы в MAX
👉@BookJava🧠 JPA: подводный камень с
@ElementCollection и fetch = FetchType.EAGER
Сегодня покажу, почему @ElementCollection(fetch = FetchType.EAGER) — скрытая угроза производительности и неожиданного поведения.
📌 Суть проблемы
При использовании @ElementCollection с EAGER Hibernate делает отдельный SELECT на каждую коллекцию, даже при JOIN FETCH на родительскую сущность.
@Entity
class User {
@Id Long id;
@ElementCollection(fetch = FetchType.EAGER)
List<String> tags;
}
Запрос findAll() приведёт к N+1 проблеме:
1 запрос на User, потом по одному на каждый tags.
💡 Почему это больно
Даже если вы используете JOIN FETCH на User, Hibernate не может сделать JOIN на @ElementCollection. Это ограничение — Hibernate всегда грузит коллекцию отдельным запросом.
⚠️ Особенно опасно при pagination
Если вы делаете Page<User> — Hibernate сначала грузит User'ов, а затем делает N запросов на коллекции. В проде это быстро становится проблемой.
✅ Что делать
1. Делайте fetch = FetchType.LAZY (по умолчанию так и есть).
2. Если нужно подгрузить коллекцию — используйте @BatchSize:
@ElementCollection
@BatchSize(size = 20)
List<String> tags;
Или вручную:
SELECT u FROM User u LEFT JOIN FETCH u.tags WHERE u.id IN :ids
👉 Следи за @ElementCollection — он не так прост, как кажется.
📲 Мы в MAX
👉@BookJava🧠 Как избежать N+1 при использовании
@OneToMany в JPA
Одна из самых коварных ловушек JPA - это N+1 проблема. Особенно часто она проявляется при @OneToMany, например:
@Entity
class Author {
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
private List<Book> books;
}
Вы загружаете список авторов, а потом проходите по каждому и вызываете getBooks() — и BAM 💥: 1 запрос на авторов и N запросов на книги.
📌 Решение - @EntityGraph или JOIN FETCH
Оба варианта решают проблему, но @EntityGraph — декларативный и более гибкий способ:
@EntityGraph(attributePaths = "books")
List<Author> findAll(); // Spring Data JPA
⚡️ Или через JPQL:
@Query("SELECT a FROM Author a JOIN FETCH a.books")
List<Author> findAllWithBooks();
💡 Совет: всегда думайте о графе объектов. Если вам нужно сразу подтянуть связанные сущности — делайте это явно. Не надейтесь на LAZY по умолчанию.
⚠️ Осторожно с пагинацией и JOIN FETCH — могут появиться дубликаты или проблемы с LIMIT. В таких случаях лучше использовать @BatchSize или подзапросы.
📲 Мы в MAX
👉@BookJavaЧем отличаются checked и unchecked исключения в java?
В Java исключения делятся на два основных типа: checked и unchecked. Разница между ними ключевая и касается как обработки, так и структуры кода.
✅ Checked Exceptions (Проверяемые исключения)
Примеры: IOException, SQLException, FileNotFoundException
Отличия:
1. Проверяются компилятором — вы обязаны либо обработать их с помощью try-catch, либо явно пробросить (throws) в сигнатуре метода.
2. Производные от Exception, но не от RuntimeException.
3. Используются для ситуаций, которые можно разумно ожидать и обработать (например, отсутствие файла, проблемы с сетью).
Пример:
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // может выбросить IOException
}
❌ Unchecked Exceptions (Непроверяемые исключения)
Примеры: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException
Отличия:
1. Не проверяются компилятором — вы не обязаны их обрабатывать или декларировать.
2. Производные от RuntimeException.
3. Возникают в результате ошибок в логике программы или непредвиденных ситуаций.
Пример:
public void printLength(String str) {
System.out.println(str.length()); // может выбросить NullPointerException
}
Если кратко:
Checked — ошибки среды, требующие явной обработки.
Unchecked — ошибки в логике, ответственность программиста.
📲 Мы в MAX
👉@BookJava🧠 JPA: не забывай про
flush() перед clear() — иначе словишь баг
Если ты используешь EntityManager вручную, например, при батчевой вставке или обновлении, то, скорее всего, пишешь что-то вроде:
for (int i = 0; i < entities.size(); i++) {
em.persist(entities.get(i));
if (i % 50 == 0) {
em.clear(); // чтобы не росла память
}
}
⚠️ Но тут баг: без flush() перед clear() ты теряешь все неперсистенные изменения! Hibernate просто забудет про них.
✅ Правильно так:
for (int i = 0; i < entities.size(); i++) {
em.persist(entities.get(i));
if (i % 50 == 0) {
em.flush();
em.clear();
}
}
📌 flush() гарантирует, что все накопленные изменения пойдут в базу, а clear() уже безопасно очищает контекст.
💡 Эта ошибка особенно коварна, потому что не всегда проявляется — зависит от настроек, триггеров в БД, кэша и т.д.
📲 Мы в MAX
👉@BookJava🚀 Подборка полезных IT каналов в Max
Системное администрирование, DevOps 📌
https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин
https://max.ru/channel_win_sysadmin Системный Администратор Windows
https://max.ru/channel_linux_admin Linux: Системный администратор
https://max.ru/channel_linuxmod Linux
https://max.ru/channel_i_linux Системный администратор
https://max.ru/channel_devopslib DevOps, SRE, Sysadmin
https://max.ru/channel_devops_star DevOps Star (Звезда Девопса)
Excel лайфхак 📌
https://t.me/Excel_lifehack Excel лайфхак
Английский с нуля 🇬🇧
https://max.ru/UchuEnglish
1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://max.ru/channel_DevLab1C 1С:Предприятие 8
Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика
https://max.ru/channel_cpp_geek C++ geek
Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика
Программирование React📌
https://max.ru/react_lib React
Программирование Rust📌
https://max.ru/channel_rust_lib
Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика
Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика
https://max.ru/channel_java_geek Java Geek
GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных
Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков
Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов
Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼💻👩💻
Шутки программистов 📌
https://max.ru/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free
Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров
Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике
Вакансии в IT📌
https://max.ru/progjob
https://max.ru/channel_rabotait
Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных
Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
🧠 Spring Boot и медленные autowire — проверь, не зарыта ли у тебя бомба в
@Configuration
Есть распространённый анти-паттерн: ты используешь @Configuration и внутри создаёшь бины с @Bean, а в этих методах — инжектишь зависимости через параметры. Всё выглядит красиво и «по фэншую»... но только на первый взгляд.
@Configuration
public class MyConfig {
@Bean
public MyService myService(SomeDep dep) {
return new MyService(dep);
}
@Bean
public SomeDep someDep() {
return new SomeDep();
}
}
⚠️ Проблема: такие методы вызываются при старте контекста, и если SomeDep создаётся долго (например, подтягивает настройки из удалённого конфига, делает init-запрос в БД, или тянет секьюрити-контекст), это тормозит весь старт.
📌 Хуже всего, если ты не подозреваешь об этом: ведь @Bean -методы не видны как "инициализация", и кажется, что контекст тормозит "где-то ещё".
💡 Совет:
- Используй @Lazy в нужных местах, особенно если bean тяжёлый или редко используется.
- Разделяй конфигурацию: отдельно core, отдельно init-heavy.
- Не бойся отказаться от @Configuration в пользу @Component + @Service, если это упрощает понимание.
И главное — профилируй старт. spring-boot-starter-actuator + --debug могут открыть глаза.
📲 Мы в MAX
👉@BookJava🧠 Lazy Initialization по-взрослому: не создавай проблемы на ровном месте
В Spring Boot часто можно встретить вот такую конструкцию:
@Service
public class EmailService {
private final SmtpClient client = new SmtpClient(); // дорогая инициализация
}
⚠️ Проблема: SmtpClient создаётся сразу при старте приложения. Даже если EmailService ни разу не вызовется. Это не только waste of resources, но и может сломать запуск, если SmtpClient требует специфического окружения.
📌 Решение — ленивая инициализация, но не через старый добрый null-check, а красиво, безопасно и читаемо:
💡 Способ #1: Lazy<T> wrapper
@Component
public class EmailService {
private final Supplier<SmtpClient> client = Suppliers.memoize(SmtpClient::new);
public void sendEmail(...) {
client.get().send(...);
}
}
Можно и без Guava:
public class Lazy<T> {
private Supplier<T> supplier;
public Lazy(Supplier<T> supplier) {
this.supplier = () -> {
T value = supplier.get();
this.supplier = () -> value;
return value;
};
}
public T get() {
return supplier.get();
}
}
💡 Способ #2: через Spring
@Service
public class EmailService {
private final ObjectProvider<SmtpClient> client;
public EmailService(ObjectProvider<SmtpClient> client) {
this.client = client;
}
public void sendEmail(...) {
client.getObject().send(...);
}
}
🧵 Итог:
- Не инициализируй тяжёлые объекты зря.
- Используй Supplier, ObjectProvider или Lazy<T>.
- Это особенно критично для тестов, лямбд и кэширования.
📲 Мы в MAX
👉@BookJava🧠 Сейчас покажу баг, который легко пропустить при работе с
@Transactional в Spring Boot 3+.
📌 Проблема — транзакция не работает, потому что метод вызывается изнутри того же класса.
Рассмотрим пример:
@Service
public class UserService {
@Transactional
public void createUser(User user) {
saveUser(user);
sendWelcomeEmail(user); // бросает исключение
}
public void saveUser(User user) {
userRepository.save(user);
}
}
💥 Если sendWelcomeEmail выбросит исключение — транзакция не откатится, потому что @Transactional работает через прокси. Вызов createUser() должен идти извне, чтобы Spring "знал", что нужно обернуть вызов в транзакцию.
✅ Решения:
1. Вынести transactional-метод в отдельный бин:
@Service
public class UserCreationService {
@Transactional
public void createUser(User user) {
// ...
}
}
2. Внедрить self-прокси:
@Autowired
private UserService self;
public void externalCaller(User user) {
self.createUser(user);
}
3. Использовать AopContext:
((UserService) AopContext.currentProxy()).createUser(user);
⚠️ Не забудь включить exposeProxy = true в @EnableAspectJAutoProxy.
💡 Современный подход — разделение ответственности: transactional-методы живут в отдельных сервисах, их проще тестировать и не возникает подобных ловушек.
📲 Мы в MAX
👉@BookJava🇷🇺 Разбираешься в радиочипах, оптике и связи?
Забери до 1 000 000 рублей за свои инженерные навыки на турнире «Дронкон» 🇷🇺
«Сталинские Соколы» открывают регистрацию на 4-й Всероссийский турнир «Дронкон», который пройдет с 22 по 26 августа.
Турнир пройдет по направлению:
- Инженерное дело: навыки программирования, сборка электронного оборудования, беспроводная связь, оптические системы + стратегия «Битва Дронов»;
Призовой фонд для победителей:
🥇место – 1 000 000 рублей 🥈место – 700 000 рублей 🥉место – 500 000 рублей Награда за 4-8 места - 100 000 рублейПройди заочный онлайн-этап и получи путевку на очный этап турнира в Республику Татарстан! Перелет, питание, проживание - за счет организаторов. 🇷🇺 Подать заявку и узнать подробности 🇷🇺
🧠 Простое ускорение
@Transactional методов в Spring Boot
Знаете, что @Transactional по умолчанию оборачивает метод в прокси?
Это значит:
- Внутренние вызовы в том же классе не проходят через транзакцию;
- Каждый такой прокси — это AOP-магия, которую можно обойти ради производительности.
📌 Если вы точно знаете, что метод будет вызываться только извне, и вам не нужна прокси-обёртка — используйте @Transactional на уровне интерфейса и включите interface-based proxy.
@Configuration
@EnableTransactionManagement(proxyTargetClass = false) // JDK proxy
public class TransactionConfig {
}
public interface UserService {
@Transactional
void createUser(User user);
}
📉 Это немного снижает overhead, особенно в высоконагруженных сервисах, где сотни тысяч вызовов @Transactional-методов.
💡 Подходит, если:
- У вас слоистая архитектура;
- Транзакции нужны только снаружи;
- Вы не используете вызовы this.someMethod() внутри сервиса.
⚠️ Не забывайте:
- JDK Proxy работает только с интерфейсами;
- Если вызываете методы внутри того же класса — прокси не сработает (и транзакция не начнётся).
📊 Профильте. Иногда замена proxyTargetClass = true на false даёт +3-5% к throughput.
📲 Мы в MAX
👉@BookJava👩💻 Основы многопоточности в Java
Приглашаем на открытый урок.
🗓 23 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
На уроке разберем:
✔️ Что такое поток выполнения и почему даже обычная Java-программа работает в главном потоке
main.
✔️ Как создавать и запускать потоки через Thread и Runnable.
✔️ Зачем нужен join и как дождаться завершения запущенных потоков.
✔️ Почему многопоточность может ускорить программу, а может добавить лишние накладные расходы.
✔️ Какие типовые проблемы возникают в многопоточном коде: гонки, starvation и deadlock.
🔗 Ссылка на регистрацию: https://vk.cc/cZD2sI
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576🧠 Как ускорить загрузку контекста Spring Boot — простой приём
Если у вас тяжёлый Spring Boot-приложение с кучей конфигураций и бинов, время старта может легко вырасти до 20–30 секунд и больше. Сегодня покажу приём, который помогает ускорить cold start за счёт отключения ненужных автоматических конфигураций.
📌 Spring Boot автоконфигурация — это палка о двух концах.
Она упрощает старт, но часто тянет за собой кучу лишнего. Особенно если вы используете
@SpringBootApplication, которая включает в себя @EnableAutoConfiguration.
💡 Решение — использовать spring.autoconfigure.exclude, чтобы явно выключить ненужное. Например:
# application.yaml
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
❗️Это особенно актуально:
- в микросервисах без UI (отключаем MVC)
- если datasource создаётся вручную
- в тестах и lightweight-режимах
👀 Как понять, что мешает?
1. Запусти приложение с флагом --debug или логгером org.springframework.boot.autoconfigure уровня DEBUG.
2. Посмотри, какие автоконфигурации "matched", но тебе не нужны.
3. Добавь их в exclude.
🧰 Альтернатива — использовать аннотацию @ImportAutoConfiguration с явным списком нужных автоконфигураций. Это тонкая настройка, идеально для библиотек и SDK.
⚠️ Не переусердствуй: отключение нужной конфигурации может привести к тихим багам. Лучше вырезать по одной и смотреть на эффект.
👉 Это один из способов сделать Spring Boot предсказуемым и быстрым, особенно в CI/CD или serverless-окружениях.
📲 Мы в MAX
👉@BookJava💡 Ленивая инициализация бинов в Spring Boot — мощный инструмент ускорения старта
По умолчанию Spring инициализирует все singleton-бины при запуске приложения. Это может быть проблемой в больших проектах: старт медленный, а половина бинов не нужна сразу.
📌 Как ускорить старт и снизить потребление памяти? — Lazy Init!
✅ Глобально:
spring:
main:
lazy-initialization: true
Все бины станут ленивыми — создадутся только при первом обращении. Это может сократить старт приложения на 30-60%!
✅ Локально (избирательно):
@Component
@Lazy
public class HeavyBean {
public HeavyBean() {
System.out.println("HeavyBean init...");
}
}
Или через @Lazy на зависимостях:
@Service
public class MyService {
public MyService(@Lazy HeavyBean heavyBean) {
this.heavyBean = heavyBean;
}
}
🧠 Когда использовать:
- В dev-окружении — чтобы ускорить локальный dev cycle.
- В CLI/Batch-приложениях, где используется 1-2 бина.
- Когда есть тяжёлые бины, не нужные на старте (например, интеграции, большие клиенты и т.п.).
⚠️ Осторожно:
- Если забыть @Lazy на зависимостях, Spring всё равно создаст бин.
- Некоторые бины должны быть загружены сразу (например, @Scheduled, @EventListener), иначе они не сработают.
📲 Мы в MAX
👉@BookJava👩💻 DAO на Spring JDBC
Приглашаем на открытый урок.
🗓 22 июля в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework».
На занятии мы разберем:
✔️Преимущества нативного SQL при разработке DAO.
✔️ Основные возможности Spring JDBC для работы с запросами.
✔️ Подходы к обеспечению безопасности и тестируемости DAO.
Кому будет интересно:
Урок будет полезен Java-разработчикам, архитекторам ПО и специалистам по базам данных, стремящимся оптимизировать доступ к данным.
🔗 Ссылка на регистрацию: https://vk.cc/cZxief
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🧠 ThreadLocal — скрытая угроза утечек памяти
ThreadLocal — удобный способ хранить данные, привязанные к потоку. Например, для
SimpleDateFormat или текущего пользователя в рамках запроса. Но с ним легко получить утечку памяти, особенно в thread pool'ах.
📌 Почему?
ThreadLocal-хранилище (Thread.threadLocals) живёт столько же, сколько поток. А потоки из пулов живут долго. Если ты забыл вызвать remove() — данные останутся в памяти навсегда.
Пример:
private static final ThreadLocal<UserContext> context = ThreadLocal.withInitial(UserContext::new);
public void handleRequest() {
try {
context.set(new UserContext("user123"));
// работа с контекстом
} finally {
context.remove(); // ОБЯЗАТЕЛЬНО!
}
}
⚠️ Что пойдёт не так без remove()?
- Поток из пула закончит обрабатывать запрос, но UserContext останется висеть в ThreadLocalMap этого потока.
- Если UserContext содержит ссылки на другие объекты (например, HttpSession, EntityManager и т.д.) — вся эта цепочка не будет GC-шиться.
- И так накапливается утечка.
💡 Советы:
- Всегда вызывай remove() в finally.
- Для Spring можно использовать RequestScope или @ControllerAdvice вместо ThreadLocal.
- Проверяй код сторонних библиотек, если они используют ThreadLocal, особенно в фильтрах и интерсепторах.
📲 Мы в MAX
👉@BookJava🧠 Как ускорить cold start Spring Boot приложения
Как можно сократить время старта Spring Boot 3+ приложения — без GraalVM и без магии.
📌 Используем флаг:
-Dspring.context.cache.applicationContext=true
💡 Что это такое?
Это встроенный механизм кэширования ApplicationContext, появившийся в Spring Boot 3.2.
Он сохраняет результат построения контекста и позволяет повторно использовать его между запусками, особенно в тестах и development-сценариях.
⚙️ Как работает:
- При первом запуске контекст билдится как обычно.
- Затем сериализуется и сохраняется на диск.
- При следующем запуске он подгружается из кеша (если не изменился), что даёт ускорение в 2-3 раза и больше.
🚀 Отлично подходит для:
- Тестов (@SpringBootTest);
- Dev tools и локального запуска;
- Разработки больших монолитов.
⚠️ Не влияет на продакшн (там кеш не используется по умолчанию)
⚠️ Не поддерживает все конфигурации (например, динамические настройки могут инвалидировать кеш)
Простой флаг — а экономит кучу времени каждый день.
📲 Мы в MAX
👉@BookJava