@EventListener как тихий убийца производительностиВ Spring удобно использовать
@EventListener для реактивных действий — казалось бы, удобно и "чисто". Но есть нюанс.📌 По умолчанию все
@EventListener вызываются синхронно и в том же потоке, где был опубликован ивент через ApplicationEventPublisher.Это значит:
@Component
public class OrderService {
@Autowired
private ApplicationEventPublisher publisher;
public void createOrder(Order order) {
// 1. Сохраняем заказ
orderRepository.save(order);
// 2. Публикуем ивент
publisher.publishEvent(new OrderCreatedEvent(order));
// 3. До выхода из метода все @EventListener уже будут выполнены
}
}
А теперь представим, что слушатель делает что-то тяжёлое:
@EventListener
public void sendEmail(OrderCreatedEvent event) {
emailService.sendConfirmation(event.getOrder());
}
⚠️ Если
sendConfirmation висит на внешнем SMTP или уходит в сеть — метод createOrder будет ждать его завершения!💡 Решение: сделать обработку асинхронной.
Просто добавьте
@Async:
@Async
@EventListener
public void sendEmail(OrderCreatedEvent event) {
emailService.sendConfirmation(event.getOrder());
}
✅ И не забудьте включить поддержку
@Async:
@EnableAsync
@Configuration
public class AsyncConfig {}
📌 Теперь
@EventListener будет исполняться в отдельном потоке из TaskExecutor, и createOrder не будет блокироваться.👉 @java_geek