赞
踩
今天在看别人的代码时,看到Spring中事件发布publishEvent,所以特地查资料,学习一下,做个笔记。原文地址:Java 创建事件Event、事件监听EventListener、事件发布publishEvent_预立科技的博客-CSDN博客
一、概述
个人认为,事件机制一般可由:事件源source,事件对象Event,事件监听EventListener,事件发布publishEvent组成
事件源:引起事件发生的源; User用户信息, Order订单信息等为事件源数据,User登录状态loginStatus引起的事件, Order状态status引起的事件
事件对象:继承ApplicationEvent,事件对象包含事件源,事件对象也就是要被监听的对象; UserEvent, OrderEvent为事件对象,
事件监听:监听事件对象,事件对象被发布触发时,事件监听到后执行处理逻辑
事件发布:触发事件的发生
发布事件publishEvent后,EventListener监听到进行默认同步处理, 线程被阻塞, 这种同步方式吞吐量小耗时,不利用程序高并发。
在实际应用过程中,事件发布或事件监听后处理逻辑应该都是异步不阻塞线程。
publishEvent或EventListener 任意一个加上异步@Async即可(程序启动类必须要添加@EnableAsync)。推荐publishEvent加异步。
如果publishEven和EventListener过程中都有大量处理数据库或其他耗时的业务,也可以两者同时加上@Async
.
举例:
1.OrderEvent订单事件中,用户进行订单支付,订单支付逻辑处理完,同步返回给用户支付完成的消息,同时发布订单事件,异步处理订单发货逻辑等,这样可以将订单支付和订单发货解耦。
2.UserEvent用户事件中,用户登录成功后,同步返回给用户登录成功的消息,同时发布用户登录事件,异步处理用户登录后记日志登录日志, 写用户购物车缓存等逻辑
.
这种事件驱动机制其实是观察者模式(又称发布订阅)具体实现,事件对象(Event)相当于被观察对象(Subject), 事件监听(EventListener) 相当于观察者(Observer)
下面是简单的代码实现二、创建事件源
- import lombok.Data;
-
- @Data
- public class User {
-
- private Long id;
-
- private String loginStatus;
- }
- package com.xxxx.model;
- import lombok.Data;
-
- @Data
- public class Order {
-
- private Long id;
-
- private Integer status;
- }
三、创建事件对象
例如:订单状态事件,用户状态事件, 需要继承ApplicationEvent
- package com.xxxx.event;
-
- import com.xxxx.model.Order;
- import org.springframework.context.ApplicationEvent;
-
- public class OrderEvent extends ApplicationEvent {
-
- private Order order;
-
- public OrderEvent(Order order) {
- //ApplicationEvent 构造函数中必须传入source对象, 官方注释中被定义为最初发生事件的对象
- super(order);
- //方式二
- //super(order.getId());
- order = order;
- }
-
- public Order getOrder(){
- return order;
- }
- }
四、事件监听
方法上添加监听事件的注解@EventListener
方法的参数为继承ApplicationEvent的事件对象
- package com.xxxx.event;
-
- import com.xxxx.model.Order;
- import com.xxxx.model.User;
- import org.springframework.context.event.EventListener;
- import org.springframework.stereotype.Component;
-
- @Component
- public class EventListenerHandle {
-
- /**
- * EventListener 监听到OrderEvent事件,触发方法
- * @param orderEvent
- */
- @Async
- @EventListener
- public void handle(OrderEvent orderEvent){
- Order order = orderEvent.getOrder();
- //getSource() 取决去构建OrderEvent时的super(source)
- //Object object = orderEvent.getSource();
-
- //处理订单业务
- if(order.getStatus() == 0){
-
- }else (order.getStatus() == 1){
-
- }else {
-
- }
- }
-
- /**
- * EventListener 监听到UserEvent事件,触发方法
- * @param userEvent
- */
- @Async
- @EventListener
- public void handle(UserEvent userEvent){
- User user = userEvent.getUser();
-
- //处理用户业务
- if(user.getLoginStatus() == 0){
-
- }else (user.getLoginStatus() == 1){
-
- }else {
-
- }
- }
- }
五、事件发布
ApplicationContext应用上下文继承了ApplicationEventPublisher,可以调用发布事件
- package com.xxxx.event;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationEvent;
- import org.springframework.stereotype.Component;
-
- @Component
- public class EventPush {
-
- /**
- * ApplicationContext 继承实现了 ApplicationEventPublisher, 可以直接发布事件
- */
- @Autowired
- private ApplicationContext applicationContext;
-
- @Async
- public void publishEvent(ApplicationEvent event){
- if (event instanceof OrderEvent) {
- applicationContext.publishEvent((OrderEvent) event);
- return;
- } else if(event instanceof UserEvent) {
- applicationContext.publishEvent((UserEvent) event);
- return;
- } else {
- //发布失败
- }
- }
-
- @Async
- public void orderEventPush(OrderEvent event){
- applicationContext.publishEvent(event);
- }
-
- @Async
- public void userEventPush(UserEvent event){
- applicationContext.publishEvent(event);
- }
- }
六、调用
注入依赖类
- @Autowired
- private EventPush eventPush;
调用事件发布
- Order order = new Order();
- order.setId(1000L);
- //0: 订单创建成功 1:支付成功 .....
- order.setStatus(1);
-
- User user = new User();
- user.setId(1000L);
- //0: 退出成功 1:登录成功 .....
- user.setLoginStatus(1);
-
- //方式一:
- eventPush.orderEventPush(new OrderEvent(order));
- eventPush.userEventPush(new UserEvent(user));
-
- //方式二:
- eventPush.publishEvent(new OrderEvent(order));
- eventPush.publishEvent(new UserEvent(user));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。