spring @EventListener 事件与监听的示例详解
作者:xixingzhe2
1、自定义Application Event
package com.ybw.event.pojo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
/**
* @className MyEvent
* @author weixiansheng
* @date 2023/9/28
* @version V1.0
**/
@Setter
@Getter
public class MyEvent extends ApplicationEvent {
private String data;
public MyEvent(Object source, String data) {
super(source);
this.data = data;
}
}2、自定义监听
package com.ybw.event.listener;
import com.ybw.event.pojo.MyEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* 简单监听
*
* @author weixiansheng
* @version V1.0
* @className MySimpleListener
* @date 2023/9/28
**/
@Component
@Slf4j
public class MySimpleListener {
/**
* @param event
* @methodName: handleDemoEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@EventListener
public void handleDemoEvent(MyEvent event) {
log.info("发布的data为:{}", event.getData());
}
}3、测试
package com.ybw.event.listener;
import com.ybw.event.pojo.MyEvent;
import com.ybw.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
/**
* @author weixiansheng
* @version V1.0
* @className MySimpleListenerTest
* @date 2023/9/28
**/
@SpringBootTest
@Slf4j
class MySimpleListenerTest {
/**
* 发布消息
*
* @methodName: publishEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@Test
public void publishEvent() throws InterruptedException {
log.info("publishEvent start");
SpringContextHolder.publishEvent(new MyEvent(this, "测试"));
log.info("publishEvent end");
TimeUnit.DAYS.sleep(1);
}
}打印日志
[INFO ] 2023-09-28 10:19:15.312 [main] c.y.e.listener.MySimpleListenerTest - publishEvent start
[INFO ] 2023-09-28 10:19:16.344 [main] c.y.event.listener.MySimpleListener - 发布的data为:测试
[INFO ] 2023-09-28 10:19:16.347 [main] c.y.e.listener.MySimpleListenerTest - publishEvent end
4、源代码
5、其他
5.1 顺序执行
使用注解
- @Order order的值越小,优先级越高。
- order如果不标注数字,默认最低优先级,因为其默认值是int最大值。
示例
/**
* 普通监听
*
* @param event
* @methodName: handleDemoEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@EventListener
@Order(2)
public void handleEvent(MyEvent event) throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
log.info("handleEvent data:{}", event.getData());
}
/**
* 条件监听
*
* @param event
* @methodName: handleConditionEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@EventListener(condition = "#event.data=='张三'")
@Order(1)
public void handleConditionEvent(MyEvent event) {
log.info("handleConditionEvent data:{}", event.getData());
}打印日志
[INFO ] 2023-09-28 10:40:22.206 [main] c.y.event.listener.MySimpleListener - handleConditionEvent data:张三
[INFO ] 2023-09-28 10:40:23.216 [main] c.y.event.listener.MySimpleListener - handleEvent data:张三
5.2 异步支持
Spring 事件机制默认是同步阻塞的,如果 ApplicationEventPublisher 发布事件之后他会一直阻塞等待listener 响应,多个 listener 的情况下前面的没有执行完后面的会一直被阻塞。发布者和订阅者属于同一事务,如果订阅者执行失败了,发布者事务会回滚。
可以利用 Spring 提供的线程池注解 @Async 来实现异步线程。异步不影响发布者的事务。
示例
/**
* 普通监听
*
* @param event
* @methodName: handleDemoEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@EventListener
public void handleEvent(MyEvent event) throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
log.info("handleEvent data:{}", event.getData());
}
/**
* 条件监听
*
* @param event
* @methodName: handleConditionEvent
* @return: void
* @author: weixiansheng
* @date: 2023/9/28
**/
@Async
@EventListener(condition = "#event.data=='张三'")
public void handleConditionEvent(MyEvent event) {
log.info("handleConditionEvent data:{}", event.getData());
}打印日志
[INFO ] 2023-09-28 10:49:40.246 [thread-pool-1] com.ybw.event.listener.MyListener - handleConditionEvent data:张三
[INFO ] 2023-09-28 10:49:41.255 [main] com.ybw.event.listener.MyListener - handleEvent data:张三
一个是线程thread-pool-1,一个是线程main。
6、总结
- 事件模式概念
- 事件:事件的触发者,比如用户注册就是事件。
- 事件发布:描述发生了什么事情的对象,比如张三注册成功的事件。
- 事件监听:监听到事件发生的时候,做一些处理,比如下单后,增加用户积分。
- Spring中事件监听器的处理是同步方式
- 日志都是都一个线程。
- 执行时顺序的,执行完监听器的业务后,会向下继续执行后面的逻辑。如上例:publishEvent end。
到此这篇关于spring @EventListener 事件与监听的文章就介绍到这了,更多相关spring @EventListener 事件与监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
