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 — головні інсайти року 
