事件流程
- 自定义事件,一般是继承ApplicationEvent抽象类
- 定义事件监听器,一般是实现ApplicationListener接口
- 发布事件
/**
* Description:定义事件
* Created by 大师兄 on 2023/10/23 20:22
*/
public class MyApplicationEvent extends ApplicationEvent {
public MyApplicationEvent(Object source) {
super(source);
}
}
/**
* Description:定义事件监听器
* Created by 大师兄 on 2023/10/23 20:24
*/
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
System.out.println("操作事件:"+myApplicationEvent.getSource().toString());
}
}
@SpringBootApplication
public class Test {
public static void main(String[] args) {
//SpringApplication.run(Test.class, args);
SpringApplication app =new SpringApplication(Test.class);
//启动时需要发监听器加到spring容器中(或者直接在监听器上加@Component)
app.addListeners(new MyApplicationListener());
ConfigurableApplicationContext context =app.run(args);
//发布事件
context.publishEvent(new MyApplicationEvent("我是一个事件!"));
context.close();
}
}
console:
操作事件:我是一个事件!
2023-11-05 13:07:42.076 INFO 4660 --- [ main]
Process finished with exit code 0
还可以通过配置项来配置监听器:
context:listener:classes: com\sycc\event\MyApplicationListener
@EventListener
将一个
方法
标记为监听器,用于监听应用程序事件,且该类也要注册到容器中
可以通过 condition
属性指定一个SpEL表达式,如果返回 "true", "on", "yes", or "1"
中的任意一个,则事件会被处理,否则不会。
示例:
单一事件监听器
发布事件:
@Service
public class EventPublisher {
private ApplicationEventPublisher eventPublisher;
@Autowired
public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void publishPersonSaveEvent(){
//新建一个事件
PersonSaveEvent saveEvent = new PersonSaveEvent();
saveEvent.setId(1);
saveEvent.setName("i余数");
saveEvent.setAge(18);
eventPublisher.publishEvent(saveEvent);
}
}
监听 事件 :
@Slf4j
@Service
public class EventListenerService {
@EventListener
public void handleForPersonSaveEvent(PersonSaveEvent saveEvent){
log.info("saveEvent -> {}", saveEvent);
}
}
结果:
只处理id等于1的 -> PersonSaveEvent(id=1, name=i余数, age=18)
使用classes实现多事件监听器
- 发布事件
- 在上一个示例的基础上,再多加一个PersonUpdateEvent事件。
public void publishPersonUpdateEvent(){
PersonUpdateEvent updateEvent = new PersonUpdateEvent();
updateEvent.setId(1);
updateEvent.setName("i余数");
updateEvent.setAge(19);
eventPublisher.publishEvent(updateEvent);
}
监听事件
@EventListener(classes = {PersonSaveEvent.class, PersonUpdateEvent.class})
public void handleForPersonSaveAndUpdateEvent(Object event){
log.info("multi handle event -> {}", event);
}
验证结果
可以监听到多个事件
multi handle event -> PersonSaveEvent(id=1, name=i余数, age=18)
multi handle event -> PersonUpdateEvent(id=1, name=i余数, age=19)
使用condition筛选监听的事件
public void publishPersonSaveEvent(){
PersonSaveEvent saveEvent = new PersonSaveEvent();
saveEvent.setId(1);
saveEvent.setName("i余数");
saveEvent.setAge(18);
eventPublisher.publishEvent(saveEvent);
PersonSaveEvent saveEvent2 = new PersonSaveEvent();
saveEvent2.setId(2);
saveEvent2.setName("i余数");
saveEvent2.setAge(18);
eventPublisher.publishEvent(saveEvent2);
}
监听事件:
@EventListener(condition = "#root.event.getPayload().getId() == 1")
public void handleByCondition(PersonSaveEvent saveEvent){
log.info("只处理id等于1的 -> {}", saveEvent);
}
结果验证
id为2的事件不满足条件,所以不会执行。
只处理id等于1的 -> PersonSaveEvent(id=1, name=i余数, age=18)
有返回值的监听器
返回一个单一对象
发布事件
public void publishPersonSaveEvent(){
PersonSaveEvent saveEvent = new PersonSaveEvent();
saveEvent.setId(1);
saveEvent.setName("i余数");
saveEvent.setAge(18);
eventPublisher.publishEvent(saveEvent);
}
监听事件
@EventListener
public void handleForPersonUpdateEvent(PersonUpdateEvent updateEvent){
log.info("handle update event -> {}", updateEvent);
}
@EventListener
public PersonUpdateEvent handleHaveReturn(PersonSaveEvent saveEvent){
log.info("handle save event -> {}", saveEvent);
PersonUpdateEvent updateEvent = new PersonUpdateEvent();
updateEvent.setId(saveEvent.getId());
updateEvent.setName(saveEvent.getName());
updateEvent.setAge(saveEvent.getAge());
return updateEvent;
}
验证结果
可以看到我们监听到了2个事件,PersonSaveEvent
是我们主动发布的事件,PersonUpdateEvent
是 handleHaveReturn
方法的返回值,会被 Spring 自动当作一个事件被发送。
handle save event -> PersonSaveEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)
返回一个集合
将监听器稍作修改,使其返回一个集合。
@EventListeners
public List<PersonUpdateEvent> handleHaveReturn(PersonSaveEvent saveEvent){
log.info("handle save event -> {}", saveEvent);
List<PersonUpdateEvent> events = new ArrayList<>();
PersonUpdateEvent updateEvent = new PersonUpdateEvent();
updateEvent.setId(saveEvent.getId());
updateEvent.setName(saveEvent.getName());
updateEvent.setAge(saveEvent.getAge());
events.add(updateEvent);
PersonUpdateEvent updateEvent2 = new PersonUpdateEvent();
BeanUtils.copyProperties(updateEvent, updateEvent2);
events.add(updateEvent2);
return events;
}
查看结果可以发现,集合中的每个对象都被当作一个单独的事件进行发送。
handle save event -> PersonSaveEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)
handle update event -> PersonUpdateEvent(id=1, name=i余数, age=18)
给个饭钱?
- Post link: http://sovzn.github.io/2023/10/23/%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues