Библиотека Java разработчика (@BookJava) — Telegram-канал | Telegram Dialogs
Все каналы
Библиотека Java разработчика

Библиотека Java разработчика

@BookJava

10.2K подписчиков технологии 💬 Комментарии открыты

📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Последние публикации

Библиотека Java разработчика
16.07.2026 16:02 · 👁 410
🧠 Сейчас покажу баг, который легко пропустить при работе с @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
Библиотека Java разработчика
16.07.2026 14:02 · 👁 455
🇷🇺 Разбираешься в радиочипах, оптике и связи? Забери до 1 000 000 рублей за свои инженерные навыки на турнире «Дронкон» 🇷🇺 «Сталинские Соколы» открывают регистрацию на 4-й Всероссийский турнир «Дронкон», который пройдет с 22 по 26 августа. Турнир пройдет по направлению: - Инженерное дело: навыки программирования, сборка электронного оборудования, беспроводная связь, оптические системы + стратегия «Битва Дронов»; Призовой фонд для победителей: 🥇место – 1 000 000 рублей 🥈место – 700 000 рублей 🥉место – 500 000 рублей Награда за 4-8 места - 100 000 рублей Пройди заочный онлайн-этап и получи путевку на очный этап турнира в Республику Татарстан! Перелет, питание, проживание - за счет организаторов. 🇷🇺 Подать заявку и узнать подробности 🇷🇺
Библиотека Java разработчика
16.07.2026 08:05 · 👁 538
🧠 Простое ускорение @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 разработчика
16.07.2026 06:04 · 👁 516
👩‍💻 Основы многопоточности в Java Приглашаем на открытый урок. 🗓 23 июля в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик». На уроке разберем: ✔️ Что такое поток выполнения и почему даже обычная Java-программа работает в главном потоке main. ✔️ Как создавать и запускать потоки через Thread и Runnable. ✔️ Зачем нужен join и как дождаться завершения запущенных потоков. ✔️ Почему многопоточность может ускорить программу, а может добавить лишние накладные расходы. ✔️ Какие типовые проблемы возникают в многопоточном коде: гонки, starvation и deadlock. 🔗 Ссылка на регистрацию: https://vk.cc/cZD2sI Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Библиотека Java разработчика
15.07.2026 07:47 · 👁 584
🧠 Как ускорить загрузку контекста 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
Библиотека Java разработчика
14.07.2026 05:54 · 👁 616
💡 Ленивая инициализация бинов в 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
Библиотека Java разработчика
13.07.2026 08:31 · 👁 689
👩‍💻 DAO на Spring JDBC Приглашаем на открытый урок. 🗓 22 июля в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework». На занятии мы разберем: ✔️Преимущества нативного SQL при разработке DAO. ✔️ Основные возможности Spring JDBC для работы с запросами. ✔️ Подходы к обеспечению безопасности и тестируемости DAO. Кому будет интересно: Урок будет полезен Java-разработчикам, архитекторам ПО и специалистам по базам данных, стремящимся оптимизировать доступ к данным. 🔗 Ссылка на регистрацию: https://vk.cc/cZxief Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Библиотека Java разработчика
11.07.2026 06:28 · 👁 814
🧠 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
Библиотека Java разработчика
09.07.2026 06:49 · 👁 886
🧠 Как ускорить 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
Библиотека Java разработчика
07.07.2026 06:30 · 👁 916
🧠 Частая ловушка при работе с @Transactional в Spring Сейчас покажу вам один распространённый анти-паттерн, который легко пропустить — вызов транзакционного метода внутри того же класса. 📌 Пример: @Service public class UserService { @Transactional public void registerUser(UserDto dto) { saveUser(dto); } @Transactional public void saveUser(UserDto dto) { // сохранение пользователя } } 💥 Проблема: Spring не применит транзакцию к saveUser(), потому что вызов происходит внутри одного и того же бина — минуя прокси. Spring AOP работает через прокси, и @Transactional "срабатывает", только если метод вызывается извне, через прокси-объект. ⚠️ Это может привести к очень странным багам: вы думаете, что транзакция есть, а её нет. 💡 Как исправить: 1. Вынести метод в отдельный бин: @Service public class UserSaver { @Transactional public void save(UserDto dto) { // сохраняем } } @Service public class UserService { private final UserSaver saver; public UserService(UserSaver saver) { this.saver = saver; } public void registerUser(UserDto dto) { saver.save(dto); } } 2. Или использовать TransactionTemplate вручную. ✅ Всегда проверяйте, как вызываются методы с @Transactional. Особенно при рефакторинге! 📲 Мы в MAX 👉@BookJava
Чат поддержки
Ответим здесь же, обычно быстро
Здравствуйте! Напишите ваш вопрос — оператор ответит в этом чате.