spring 事件

Spring提供了事件机制,其本质是JDK提供的事件机制的应用,利用的是观察者设计模式,具体请看设计模式之观察者模式(Observer Pattern)。
主要成员:
ApplicationEvent:发布事件消息载体
ApplicationListener:监听器
@EventListener:注解事件监听器
代码示例:
监听器

@Component
public class MyEventListen{

    /**
     * 异步和发布方法在同一个事务中
     */
    @Async
    @TransactionalEventListener(MyEvent.class)
    public void myEvent(MyEvent event) {
        System.out.println("线程名称"+Thread.currentThread().getName()+"监听到MyEvent消息了");
        System.out.println("监听到了spring消息,消息体:"+ JSONObject.toJSONString(event.getSource()));
    }

    /**
     * 同步监听
     * @param event
     */
    @EventListener(OtherEvent.class)
    public void onApplicationEvent(OtherEvent event) {
        System.out.println("线程名称"+Thread.currentThread().getName()+"监听到OtherEvent消息了");
        System.out.println("监听到了spring消息,消息体:"+ JSONObject.toJSONString(event.getSource()));
    }
}

事件消息载体示例

public class MyEvent extends ApplicationEvent {

    public MyEvent(EventDTO source) {
        super(source);
    }
}
@Data
@EqualsAndHashCode(callSuper = false)
public class EventDTO {

    private String tager;

    private String msg;

}
public class OtherEvent extends ApplicationEvent {


    public OtherEvent(OtherDto dto) {
        super(dto);
    }

    @Data
    @EqualsAndHashCode(callSuper = false)
    public static class OtherDto{

        /**请求头*/
        private String title;

        /**消息*/
        private String msg;

    }
}

发布事件

    @Resource
    private ApplicationContext applicationContext;


    public void publishMyEvent() throws InterruptedException {
        System.out.println("线程名称"+Thread.currentThread().getName()+"发布消息");
        EventDTO eventDTO = new EventDTO();
        eventDTO.setMsg("spring event消息");
        eventDTO.setTager("place");
        applicationContext.publishEvent(new MyEvent(eventDTO));
        Thread.sleep(1000);
        System.out.println("线程名称"+Thread.currentThread().getName()+"跑完了");
    }

    public void publishOtherEvent() throws InterruptedException {
        System.out.println("线程名称"+Thread.currentThread().getName()+"发布消息");
        OtherEvent.OtherDto eventDTO = new OtherEvent.OtherDto();
        eventDTO.setMsg("spring event消息");
        eventDTO.setTitle("other");
        applicationContext.publishEvent(new OtherEvent(eventDTO));
        Thread.sleep(1000);
        System.out.println("线程名称"+Thread.currentThread().getName()+"跑完了");
    }

测试类

    @Resource
    private MyEventPublish eventPublish;

    @Test
    public void testPublish() throws InterruptedException {
        eventPublish.publishMyEvent();

        eventPublish.publishOtherEvent();
    }

输出结果

线程名称main发布消息
线程名称task-1监听到MyEvent消息了
监听到了spring消息,消息体:{"msg":"spring event消息","tager":"place"}
线程名称main跑完了
线程名称main发布消息
线程名称main监听到OtherEvent消息了
监听到了spring消息,消息体:{"msg":"spring event消息","title":"other"}
线程名称main跑完了

如果加了@Async注解,发现监听器和发布事件的还是同一个线程,则检查下是否启动类中没有加 @EnableAsync 这个注解

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容