前言: 事件監聽模型是一種經常使用的設計模式,在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()); } }