spring|spring event|Spring内置事件驱动编程模型|顺序和条件
事件执行谁来决定
类型匹配(Type Match)、条件过滤(Condition Filter) 和顺序排序(Ordering)共同决定了事件最终由谁执行、何时执行
源码
https://gitee.com/jysemel-spring/spring-boot/tree/master/action/action-event-order
核心流程图解
第一步(类型匹配) -> 第二步(顺序排序) -> 第三步(条件过滤) -> 第四步(事务相位对齐) -> 执行
条件触发(Condition)结合SpEL表达式
- 代码演示
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Slf4j
@Component
public class CouponListener {
@Async("eventExecutor")
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
log.info("默认 全量监控 ");
log.info("赠送新人优惠券给用户:{} ", event.getNickName());
}
}
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Slf4j
@Component
public class CouponListener1 {
@Async("eventExecutor")
@EventListener(condition = "#event.userName == 'test'")
public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
log.info("满足 test ");
log.info("赠送新人优惠券给用户:{} ", event.getNickName());
}
}
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Slf4j
@Component
public class CouponListener2 {
@Async("eventExecutor")
@EventListener(condition = "#event.userName == 'ddd'")
public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
log.info("满足 ddd ");
log.info("赠送新人优惠券给用户:{} ", event.getNickName());
}
}
请求访问 http://127.0.0.1:8083/api/user/reg?userName=test&nickName=222
验证结果
2026-07-14 14:32:19.502 [http-nio-8083-exec-7] [] INFO com.jysemel.spring.boot.study.controller.UserRegController - 用户注册:test
2026-07-14 14:32:19.502 [http-nio-8083-exec-7] [] INFO com.jysemel.spring.boot.study.service.StoreService - 用户 222 注册成功
2026-07-14 14:32:19.504 [event-async-4] [] INFO com.jysemel.spring.boot.study.listener.CouponListener - 默认 全量监控
2026-07-14 14:32:19.504 [event-async-4] [] INFO com.jysemel.spring.boot.study.listener.CouponListener - 赠送新人优惠券给用户:222
2026-07-14 14:32:19.504 [event-async-5] [] INFO com.jysemel.spring.boot.study.listener.CouponListener1 - 满足 test
2026-07-14 14:32:19.504 [event-async-5] [] INFO com.jysemel.spring.boot.study.listener.CouponListener1 - 赠送新人优惠券给用户:222
顺序触发(Order)没有order最后执行
- 代码演示
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Slf4j
@Component
public class OrderListener1 {
@EventListener
@Async("eventExecutor")
@Order(1)
public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
log.info("我是顺序一...................... ");
log.info("赠送新人优惠券给用户:{} ", event.getNickName());
}
}
package com.jysemel.spring.boot.study.listener;
import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 方式二:使用@EventListener注解(更推荐)
*/
@Slf4j
@Component
public class OrderListener2 {
@EventListener
@Async("eventExecutor")
@Order(99)
public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
log.info("我是顺序二......................排序99 ");
log.info("赠送新人优惠券给用户:{} ", event.getNickName());
}
}
- 演示结果
http://127.0.0.1:8083/api/user/reg?userName=test&nickName=222
2026-07-14 14:49:06.177 [http-nio-8083-exec-1] [] INFO com.jysemel.spring.boot.study.controller.UserRegController - 用户注册:test
2026-07-14 14:49:06.178 [http-nio-8083-exec-1] [] INFO com.jysemel.spring.boot.study.service.StoreService - 用户 222 注册成功
2026-07-14 14:49:11.194 [event-async-3] [] INFO com.jysemel.spring.boot.study.listener.CouponListener - 默认 全量监控
2026-07-14 14:49:11.194 [event-async-1] [] INFO com.jysemel.spring.boot.study.listener.OrderListener1 - 我是顺序一......................
2026-07-14 14:49:11.194 [event-async-2] [] INFO com.jysemel.spring.boot.study.listener.OrderListener2 - 我是顺序二......................排序99
2026-07-14 14:49:11.194 [event-async-1] [] INFO com.jysemel.spring.boot.study.listener.OrderListener1 - 赠送新人优惠券给用户:222
2026-07-14 14:49:11.194 [event-async-2] [] INFO com.jysemel.spring.boot.study.listener.OrderListener2 - 赠送新人优惠券给用户:222
2026-07-14 14:49:11.194 [event-async-3] [] INFO com.jysemel.spring.boot.study.listener.CouponListener - 赠送新人优惠券给用户:222
2026-07-14 14:49:11.209 [event-async-4] [] INFO com.jysemel.spring.boot.study.listener.CouponListener1 - 满足 test
2026-07-14 14:49:11.209 [event-async-4] [] INFO com.jysemel.spring.boot.study.listener.CouponListener1 - 赠送新人优惠券给用户:222
