Spring Boot中消息事件机制的原理是什么

来源:互联网转载和整理 2024-05-04 08:12:17

springboot原理

本篇文章给大家分享的是有关Spring Boot中消息事件机制的原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

Spring Boot自带了消息机制,可以让我们在一个地方发布消息,多个地方同时接收消息并处理消息,当然这是在同一个JVM内存下进行的,不同的进程还需要使用MQ来实现。我觉得该消息模式跟观察者模式有一定的区别,观察者模式一般观察的是一个对象内部属性发生变化的时候使用。而该消息机制可以在任意地方使用。

消息事件本身是一个对象,继承于ApplicationEvent

@DatapublicclassDemoEventextendsApplicationEvent{privateStringtype;privateList<Map>msg;publicDemoEvent(Objectsource,Stringtype,List<Map>msg){super(source);this.type=type;this.msg=msg;}}

还需要有一个消息事件发布者,将这个消息事件给发布出去

@ComponentpublicclassDemoPublisher{@AutowiredApplicationContextapplicationContext;publicvoidpublish(DemoEventdemoEvent){applicationContext.publishEvent(demoEvent);}}

然后就是我们的侦听者,侦听者可以有任意个根据业务不同做不同的处理,他的写法分两种,一个是实现了ApplicationListener接口,一个是在方法上打上@EventListener标签

@Component@Slf4jpublicclassDemoListenerimplementsApplicationListener<DemoEvent>{@Override@AsyncpublicvoidonApplicationEvent(DemoEventdemoEvent){log.info("接收到publisher发送到消息,时间"+Time.getTime());List<Map>msg=demoEvent.getMsg();Stringtype=demoEvent.getType();try{Thread.sleep(3000);}catch(Exceptione){e.printStackTrace();}log.info("类型"+type+",消息内容:"+msg);}}
@Component@Slf4jpublicclassDemoListener1{@EventListenerpublicvoidonDemoEvent(DemoEventdemoEvent){log.info("listener1通过注解接收到了publisher发送的消息,时间"+Time.getTime());Stringtype=demoEvent.getType();List<Map>msg=demoEvent.getMsg();try{Thread.sleep(2000);}catch(Exceptione){e.printStackTrace();}log.info("listener1:类型"+type+",消息内容:"+msg);}}

但是我们需要知道的是,多个消息监听是同步执行的,他们会发生阻塞,所以我们需要进行异步监听,实现异步监听只需要在方法上打上@Async标签,同时在Springboot主程序中开启允许异步

@EnableAsync@SpringBootApplicationpublicclassLanmdaApplication{publicstaticvoidmain(String[]args){SpringApplication.run(LanmdaApplication.class,args);}}

最后写一个测试的Controller

@Slf4j@RestControllerpublicclassTestController{@AutowiredprivateDemoPublisherpublisher;@GetMapping("/test")publicStringtestListener(){List<Map>list=newArrayList<>();Map<String,String>m1=newHashMap<>();m1.put("1","2");Map<String,String>m2=newHashMap<>();m2.put("3","4");Map<String,String>m3=newHashMap<>();m3.put("5","6");list.add(m1);list.add(m2);list.add(m3);log.info("开始发布消息:"+Time.getTime());publisher.publish(newDemoEvent(this,"测试消息",list));log.info("消息发布结束:"+Time.getTime());return"消息发布成功";}}

执行后,日志如下

2019-07-21 10:42:39.686 INFO 1756 --- [nio-8080-exec-1] c.g.lanmda.controller.TestController : 开始发布消息:10:42:39
2019-07-21 10:42:39.687 INFO 1756 --- [nio-8080-exec-1] com.guanjian.lanmda.event.DemoListener1 : listener1通过注解接收到了publisher发送的消息,时间10:42:39
2019-07-21 10:42:41.690 INFO 1756 --- [nio-8080-exec-1] com.guanjian.lanmda.event.DemoListener1 : listener1:类型测试消息,消息内容:[{1=2}, {3=4}, {5=6}]
2019-07-21 10:42:41.695 INFO 1756 --- [nio-8080-exec-1] .s.a.AnnotationAsyncExecutionInterceptor : No task executor bean found for async processing: no bean of type TaskExecutor and no bean named 'taskExecutor' either
2019-07-21 10:42:41.697 INFO 1756 --- [nio-8080-exec-1] c.g.lanmda.controller.TestController : 消息发布结束:10:42:41
2019-07-21 10:42:41.697 INFO 1756 --- [cTaskExecutor-1] com.guanjian.lanmda.event.DemoListener : 接收到publisher发送到消息,时间10:42:41
2019-07-21 10:42:44.701 INFO 1756 --- [cTaskExecutor-1] com.guanjian.lanmda.event.DemoListener : 类型测试消息,消息内容:[{1=2}, {3=4}, {5=6}]