Большинство разработчиков в Spring знают, как доставать query-параметры и path variables.
Но часто забывают, что HTTP-хедеры можно вытаскивать так же просто. В Spring для этого есть аккуратный
Можно в одну строку получить
Пример:
▪️ Добавляешь в метод контроллера
▪️ Spring сам подхватывает значение из заголовка
▪️ Ты получаешь его сразу параметром метода
Нужно сделать опциональным?
Просто добавь
Нужен дефолт?
▪️ Используй
▪️ Очень полезно для логирования, аналитики, A/B тестов или фичефлагов, завязанных на заголовки.
▪️ Выручает при работе с API-клиентами, которые шлют кастомные заголовки.
▪️ Чище, короче и легче тестируется.
▪️ Чем меньше зависимостей от servlet API, тем лучше.
👉 Java Portal
Но часто забывают, что HTTP-хедеры можно вытаскивать так же просто. В Spring для этого есть аккуратный
@RequestHeader.Можно в одну строку получить
User-Agent, Authorization или любой кастомный хедер. И не нужно лезть в HttpServletRequest.Пример:
@RequestHeader("User-Agent") String userAgentНужно сделать опциональным?
Просто добавь
required = false.Нужен дефолт?
defaultValue = "unknown".Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
Java-совет: чтобы не ловить оверхед на boxing/unboxing, используй стримы примитивов (IntStream/LongStream/DoubleStream) вместо Stream<Integer>/Stream<Long>/Stream<Double>.
❌ Создаём объекты Integer для каждого значения:
✅ Работаем напрямую с int:
✅ Другие примитивные стримы:
👉 Java Portal
Stream<Integer> boxed = Stream.of(1, 2, 3, 4, 5);
int sumBoxed = boxed.reduce(0, Integer::sum);
int sumPrimitive = IntStream.of(1, 2, 3, 4, 5).sum();
LongStream, DoubleStreamPlease open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3
Как прогревать кэши в Spring Boot?
И вообще, как делать что-то на старте приложения?
Обычно такие операции делают в
Если “прогрев” лежит в
Покажу более элегантный способ “прогрева кэшей”. В какой-то момент точно пригодится.
Смотри:
В чём плюс?
В интеграционных тестах с
Когда всё-таки нужно, чтобы “прогрев” выполнялся и в тестах, добавь параметр “использовать main метод”:
И всё. Если код должен выполняться после старта, но мешает тестам, клади его в
👉 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. Очень полезный приём.Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Spring Boot: можно использовать
Что это делает:
▪️ Делает 3 ретрая, если вылетают указанные исключения.
▪️ Стартует с задержки 2 секунды и удваивает ее на каждой попытке (экспоненциальный backoff).
▪️ Если все попытки провалились, вызывает recover().
👉 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");
}
}
Что это делает:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Вопрос для собеседования по Spring Boot:
Какой будет результат запуска, если активный профиль не указан?
❓ Spring по умолчанию выберет бин
❓ Spring выберет первый бин в алфавитном порядке
❓ Приложение упадет с
❓ Бины не будут созданы, но приложение запустится
❓ Будут созданы оба бина -
👉 Java Portal
Какой будет результат запуска, если активный профиль не указан?
DevNotificationServiceNoSuchBeanDefinitionExceptionNoUniqueBeanDefinitionExceptionPlease open Telegram to view this post
VIEW IN TELEGRAM