Using Spring Application Events for Synchronous and Asynchronous Processing
This article explains how to leverage Spring Application Events to decouple business logic, demonstrates creating custom events, listeners, and publishers, shows both synchronous and asynchronous handling with @EventListener and @Async, and provides complete code samples and test results.
Preface – In complex business scenarios, coupling can become high; Spring Event (Application Event) offers a lightweight observer pattern to decouple components without the overhead of a full message queue.
Spring Event – Synchronous Usage – Define a custom event class extending ApplicationEvent , implement a listener (either by implementing ApplicationListener or using @EventListener ), and publish the event via ApplicationEventPublisher . The article provides the full Java code for OrderProductEvent , its listener, and the service that publishes the event.
import lombok.Data;
import lombok.ToString;
import org.springframework.context.ApplicationEvent;
@Data
@ToString
public class OrderProductEvent extends ApplicationEvent {
private String orderId;
public OrderProductEvent(Object source, String orderId) {
super(source);
this.orderId = orderId;
}
} import com.csp.mingyue.event.events.OrderProductEvent;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class OrderProductListener implements ApplicationListener
{
@SneakyThrows
@Override
public void onApplicationEvent(OrderProductEvent event) {
String orderId = event.getOrderId();
long start = System.currentTimeMillis();
Thread.sleep(2000);
long end = System.currentTimeMillis();
log.info("{}:校验订单商品价格耗时:({})毫秒", orderId, (end - start));
}
} import com.csp.mingyue.event.events.OrderProductEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
private final ApplicationContext applicationContext;
public String buyOrder(String orderId) {
long start = System.currentTimeMillis();
// 1. query order details
// 2. validate price (synchronous)
applicationContext.publishEvent(new OrderProductEvent(this, orderId));
// 3. send SMS/email (asynchronous)
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:({})毫秒", end - start);
return "购买成功";
}
}The article also includes a JUnit test that invokes buyOrder and shows the log output confirming synchronous processing time (~2000 ms) and total task time (~2009 ms).
Spring Event – Asynchronous Usage – By adding @EnableAsync to the main application class and annotating listener methods with @Async , the same event handling can run in separate threads. The article provides the updated listener code using @EventListener and @Async , and shows asynchronous test logs where the SMS/email processing runs on a task‑1 thread.
@EnableAsync
@SpringBootApplication
public class MingYueSpringbootEventApplication {
public static void main(String[] args) {
SpringApplication.run(MingYueSpringbootEventApplication.class, args);
}
} @Async
@SneakyThrows
@EventListener(MsgEvent.class)
public void sendMsg(MsgEvent event) {
String orderId = event.getOrderId();
long start = System.currentTimeMillis();
log.info("开发发送短信");
log.info("开发发送邮件");
Thread.sleep(4000);
long end = System.currentTimeMillis();
log.info("{}:发送短信、邮件耗时:({})毫秒", orderId, (end - start));
}Test results demonstrate that the main thread finishes after ~2017 ms while the asynchronous task continues, confirming the non‑blocking behavior.
Finally, the article encourages readers to discuss, ask questions, and join a community group, and provides links to additional resources and interview questions.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.