Java Portal | Программирование
12.8K subscribers
1.24K photos
104 videos
38 files
1.19K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Большинство разработчиков в Spring знают, как доставать query-параметры и path variables.

Но часто забывают, что HTTP-хедеры можно вытаскивать так же просто. В Spring для этого есть аккуратный @RequestHeader.

Можно в одну строку получить User-Agent, Authorization или любой кастомный хедер. И не нужно лезть в HttpServletRequest.

Пример:

▪️Добавляешь в метод контроллера @RequestHeader("User-Agent") String userAgent
▪️Spring сам подхватывает значение из заголовка
▪️Ты получаешь его сразу параметром метода

Нужно сделать опциональным?
Просто добавь required = false.

Нужен дефолт?

▪️Используй defaultValue = "unknown".
▪️Очень полезно для логирования, аналитики, A/B тестов или фичефлагов, завязанных на заголовки.
▪️Выручает при работе с API-клиентами, которые шлют кастомные заголовки.
▪️Чище, короче и легче тестируется.
▪️Чем меньше зависимостей от servlet API, тем лучше.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
...Script


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁144
Java-совет: чтобы не ловить оверхед на boxing/unboxing, используй стримы примитивов (IntStream/LongStream/DoubleStream) вместо Stream<Integer>/Stream<Long>/Stream<Double>.

Создаём объекты Integer для каждого значения:

Stream<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
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3
Как прогревать кэши в Spring Boot?

И вообще, как делать что-то на старте приложения?

Обычно такие операции делают в @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 Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Spring Boot: можно использовать @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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Вопрос для собеседования по Spring Boot:

Какой будет результат запуска, если активный профиль не указан?

Spring по умолчанию выберет бин DevNotificationService
Spring выберет первый бин в алфавитном порядке
Приложение упадет с NoSuchBeanDefinitionException
Бины не будут созданы, но приложение запустится
Будут созданы оба бина - NoUniqueBeanDefinitionException

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM