Java Portal | Программирование
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика Связь: @devmangx РКН: https://clck.ru/3H4WUg
Больше📈 Аналитический обзор Telegram-канала Java Portal | Программирование
Канал Java Portal | Программирование (@java_iibrary) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 12 132 подписчиков, занимая 10 377 место в категории Технологии и приложения и 54 419 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 12 132 подписчиков.
Согласно последним данным от 05 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -142, а за последние 24 часа — -1, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 11.75%. В первые 24 часа после публикации контент обычно набирает 6.20% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 1 426 просмотров. В течение первых суток публикация набирает 753 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 4.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как boot, string, void, архитектура, resttemplate.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика
Связь: @devmangx
РКН: https://clck.ru/3H4WUg”
Благодаря высокой частоте обновлений (последние данные получены 07 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
@WebMvcTest — он поднимет только MVC-бины (контроллеры, конфиг MVC, конвертеры, валидацию и т.п.), без полного контекста приложения.
▪️Он грузит только MVC-бины, а не весь application context целиком.
▪️Интеграционные тесты медленнее юнитов, поэтому их стоит ускорять, выкидывая все лишнее, что не нужно конкретно для MVC.
▪️В этом примере мы мокaем бин HelloService и поднимаем только MVC-контекст и сам контроллер:
@WebMvcTest(HelloController.class)
class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private HelloService helloService; // замокано
@Test
void sayHello_returnsExpectedMessage() throws Exception {
given(helloService.getMessage()).willReturn("Hello!");
mockMvc.perform(get("/api/hello"))
.andExpect(status().isOk())
.andExpect(content().string("Hello!"));
}
}
👉 Java Portal@SpringBootApplication(exclude = …), чтобы отключить конкретные классы автоконфигурации.
✅ Одна из возможных причин: кастомная конфигурация конфликтует с дефолтной.
👉 Java PortalfindByEmail()?
1. SELECT * FROM users WHERE email LIKE ?
2. SELECT id, name, email FROM users WHERE email LIKE ?
3. SELECT * FROM users WHERE email = ? LIMIT 1
4. SELECT * FROM users WHERE email = ?
5. SELECT * FROM users WHERE email = email
👉 Java Portal// С иммутабельными объектами:
record Book(String title, int price) {} // Иммутабельный
public class BookJob implements Runnable {
private final Book book;
.... // конструктор
@Override
public void run() {
System.out.println(book.title() + " " + book.price());
}
}
// Обмен сообщениями:
...
new Thread(() -> {
try {
queue.put("mess1");
} catch (InterruptedException e) {}
}).start();
...
new Thread(() -> {
try {
String mess = queue.take();
} catch (InterruptedException e) {}
}).start();
👉 Java PortalDevNotificationService
❓ Spring выберет первый бин в алфавитном порядке
❓ Приложение упадет с NoSuchBeanDefinitionException
❓ Бины не будут созданы, но приложение запустится
❓ Будут созданы оба бина - NoUniqueBeanDefinitionException
👉 Java Portal@Retryable, чтобы переживать нестабильность внешних сервисов.
@Service
public class ExtService {
@Retryable(
value = { HttpServerErrorException.class, ResourceAccessException.class },
maxAttempts = 3,
backoff = @Backoff(delay = 2000, multiplier = 2)
)
public ExtServiceResponse process(ExtServiceRequest request) {
// Call external payment gateway
return restTemplate.postForObject("https://ext-gateway/api/service", request,
ExtServiceResponse.class);
}
@Recover
public ExtServiceResponse recover(Exception e, ExtServiceRequest request) {
// Fallback logic after retries are exhausted
log.error("Failed after retries: {}", e.getMessage());
return new ExtServiceResponse("FAILED");
}
}
Что это делает:
▪️Делает 3 ретрая, если вылетают указанные исключения.
▪️Стартует с задержки 2 секунды и удваивает ее на каждой попытке (экспоненциальный backoff).
▪️Если все попытки провалились, вызывает recover().
👉 Java Portal@PostConstruct или ловят событие ApplicationReadyEvent. Но у этих вариантов есть заметный минус.
Если “прогрев” лежит в @PostConstruct, как его отключать в тестах? Можно завести флаг, сделать наследника и подменять бин в тестовой конфигурации, но это не всегда помогает и часто выглядит как костыль.
Покажу более элегантный способ “прогрева кэшей”. В какой-то момент точно пригодится.
Смотри: SpringApplication.run(...) возвращает полностью готовый контекст. Из него можно получить нужный компонент и вызвать метод “прогрева”. Код выглядит так:
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MainApplication.class, args);
AccountService accService = ctx.getBean(AccountService.class);
accService.loadDictionary();
}
}
В чём плюс?
В интеграционных тестах с @SpringBootTest метод main не запускается. Значит, код внутри не выполняется. Никаких костылей вокруг @PostConstruct, всё чисто и аккуратно.
Когда всё-таки нужно, чтобы “прогрев” выполнялся и в тестах, добавь параметр “использовать main метод”:
@SpringBootTest(useMainMethod = SpringBootTest.UseMainMethod.ALWAYS)
И всё. Если код должен выполняться после старта, но мешает тестам, клади его в main. Очень полезный приём.
👉 Java PortalStream<Integer> boxed = Stream.of(1, 2, 3, 4, 5);
int sumBoxed = boxed.reduce(0, Integer::sum);
✅Работаем напрямую с int:
int sumPrimitive = IntStream.of(1, 2, 3, 4, 5).sum();
✅Другие примитивные стримы:
LongStream, DoubleStream
👉 Java Portal@RequestHeader.
Можно в одну строку получить User-Agent, Authorization или любой кастомный хедер. И не нужно лезть в HttpServletRequest.
Пример:
▪️Добавляешь в метод контроллера @RequestHeader("User-Agent") String userAgent
▪️Spring сам подхватывает значение из заголовка
▪️Ты получаешь его сразу параметром метода
Нужно сделать опциональным?
Просто добавь required = false.
Нужен дефолт?
▪️Используй defaultValue = "unknown".
▪️Очень полезно для логирования, аналитики, A/B тестов или фичефлагов, завязанных на заголовки.
▪️Выручает при работе с API-клиентами, которые шлют кастомные заголовки.
▪️Чище, короче и легче тестируется.
▪️Чем меньше зависимостей от servlet API, тем лучше.
👉 Java Portalpublic class CacheUtils {
private static Map<String, String> cache = new HashMap<>();
...
}
// Кэш как выше разделяется между всеми потоками и может случайно изменяться
@Component
@Scope("request")
public class CacheService {
private Map<String, String> cache = new HashMap<>();
...
}
// Если оформить это как бин, можно задать ему конкретный scope.
// Spring лучше управляет объектами с состоянием.
👉 Java Portal@Version.
✅Идеально подходит, когда:
- чтения происходят часто
- записи сравнительно редкие
- конфликты случаются нечасто
❌Не лучший вариант, когда:
- конфликты происходят часто
- нужна строгая сериализация
public class Account {
@Id
private Long id;
private BigDecimal balance;
@Version
private Long version;
}
Когда читаем, Entity загружается с текущей версией. Допустим, version = 2.
Когда делаем update, учитывается запись с version = 2.
Если за это время другая транзакция уже успела её обновить, version уже не 2, апдейт не затронет ни одной строки, и Hibernate кинет OptimisticLockException.
То есть конфликт ловится без блокировки строки.
👉 Java PortalgetReferenceById(id) без SELECT и использовать её, чтобы задать relation.
@Service
public SomeService {
@Autowired
private ProductRepository productRepository;
@Autowired
private CategoryRepository featureRepository;
public void setCategory(long productId, long categoryId) {
Product product = productRepository.findById(productId).orElseThrow(); // executes SELECT
Category category = categoryRepository.getReferenceById(categoryId); // does not execute a SELECT
product.setCategory(category);
productRepository.save(product);
}
}
👉 Java PortalThreadLocal.withInitial(...), чтобы каждому потоку задавать своё безопасное значение по умолчанию.
Значение создаётся лениво (только при первом обращении).
👉 Java Portal
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
