前言: 事件监听模型是一种经常使用的设计模式,在springboot 中咱们如何实现呢?
首先咱们要理解事件监听中须要的几个角色web
废话很少说直接上代码spring
事件自己须要继承ApplicationEvent设计模式
package com.yxd; import java.util.List; import java.util.Map; import org.springframework.context.ApplicationEvent; public class DemoEvent extends ApplicationEvent{ private String type; private List<Map> msg; public DemoEvent(Object object, String type ,List<Map> msg) { super(object); this.msg = msg; this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } public List<Map> getMsg() { return msg; } public void setMsg(List<Map> msg) { this.msg = msg; } }
如图:
springboot
事件源须要注入 ApplicationContext app
package com.yxd; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @Component public class DemoPublisher { @Autowired ApplicationContext applicationContext; public void publish(DemoEvent event) { applicationContext.publishEvent(event); } }
监听者有两种实现异步
package com.yxd; import java.util.List; import java.util.Map; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class DemoListener1 implements ApplicationListener<DemoEvent> { @Override public void onApplicationEvent(DemoEvent event) { List<Map> msg = event.getMsg(); String type = event.getType(); System.out.println(" listener1接收到了 publisher 发送的消息 , 时间 "+ Time.getTime()); System.out.println("listener1 : 类型 :" + type +", 消息内容: " + msg + ", 消息处理完毕! "+ Time.getTime()); } }
package com.yxd; import java.util.List; import java.util.Map; import org.springframework.context.ApplicationListener; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class DemoListener2 { @EventListener public void onDemoEvent(DemoEvent demoEvent) { System.out.println(" listener2 经过注解接收到了 publisher 发送的消息 , 时间 "+ Time.getTime()); List<Map> msg = demoEvent.getMsg(); String type = demoEvent.getType(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("listener2 : 类型 :" + type +", 消息内容: " + msg + ", 消息处理完毕! "+ Time.getTime()); } }
此处咱们还须要注意一点,此处多个监听是同步执行的(阻塞),通常状况下咱们发布一个事件,是不关心谁来处理,以及处理结果的,因此咱们还须要加上异步的注解ide
package com.yxd; import java.util.List; import java.util.Map; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component public class DemoListener3 implements ApplicationListener<DemoEvent> { @Override @Async public void onApplicationEvent(DemoEvent event) { System.out.println(" listener3 接收到了 publisher 发送的消息 , 时间 "+ Time.getTime()); List<Map> msg = event.getMsg(); String type = event.getType(); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("listener3 异步执行:类型 :" + type +", 消息内容: " + msg+ ", 消息处理完毕! "+ Time.getTime()); } }
package com.yxd; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @EnableAsync @SpringBootApplication @RestController public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Autowired DemoPublisher demoPublisher; @RequestMapping("testListener") public String testListener() { ArrayList<Map> list = new ArrayList<>(); HashMap<String, String> m1 = new HashMap<>(); m1.put("1", "2"); HashMap<String, String> m2 = new HashMap<>(); m2.put("3", "4"); HashMap<String, String> m3 = new HashMap<>(); m3.put("5", "6"); list.add(m1); list.add(m2); list.add(m3); System.out.println("开始发布消息: " + Time.getTime()); demoPublisher.publish(new DemoEvent(this,"测试消息",list)); System.out.println("消息发布结束: " + Time.getTime()); return "消息发布成功"; } }
咱们访问接口
测试
三个监听者都获得了消息。。
可是 listener2 经过注解 先获得了消息,延时2秒后,listener1 才获得消息,listener1 处理完后,主线程继续执行,同时listener3 开始接收到消息,开启了一个异步任务,3秒后执行结束this
最后附上Time类
package com.yxd; import java.text.SimpleDateFormat; import java.util.Date; public class Time { public static String getTime() { return new SimpleDateFormat("HH:mm:ss").format(new Date()); } }