Spring的Event
1 简介:
只要是事件就是观察者模式,Spring中的Event也不例外,主要应用就是程序解耦,实现本质是广播的形式........屁话不多说
2 Spring的event实现方式:
继承ApplicationEvent即可,但是Spring版本4.2之后不再强制要求继承ApplicationEvent,非Application的子类将被封装成PayloadApplicationEvent:
实现:
import org.springframework.context.ApplicationEvent;public class MyEvent extends ApplicationEvent {//todo ----- private String msg;public MyEvent(Object source) {super(source);}public MyEvent(Object source,String msg) {super(source);this.msg=msg;}public String getMsg() {return msg;}
}
3 事件的推送:
编写事件推送的service实现ApplicationContextAwar接口,或者实现ApplicationEventPublisherAware接口,在需要时候根据业务场景推送事件:
实现:
@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {//实现方式一private ApplicationContext applicationContext;//实现方式二private ApplicationEventPublisher applicationEventPublisher;/*** 容器初始化时候会自动的填装该对象* @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 容器初始化时候会自动的填装该对象* @param applicationEventPublisher*/@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher=applicationEventPublisher;}/*** 实际业务中进行封装数据推送*/public void sentEvent(){//方式一:applicationContext的推送Api可以以根据需要进行选择applicationContext.publishEvent(new MyEvent(this,"我是一颗小码农"));//方式二: applicationEventPublisher的推送Api可以以根据需要进行选择applicationEventPublisher.publishEvent(new MyEvent(this,"今天是20220804"));}
}
4事件监听器(处理器):
编写事件的处理器,交给Spring的ioc管理即可,实现有两种方式,
(1)通过@EventListener注解标注对应的事件处理器,处理器会根据参数类型自动识别事件类型的
实现:
@Configuration
public class EventConfig {@EventListenerpublic void doWithEvent(MyEvent myEvent) {System.out.println("事件消息是: "+myEvent.getMsg());}@EventListenerpublic void doWithEvent(BEvent myEvent) {System.out.println("事件消息是: "+myEvent.getMsg());}@EventListenerpublic void doWithEvent(CEvent myEvent) {System.out.println("事件消息是: "+myEvent.getMsg());}
}
(2) 实现ApplicationListener<T>接口,处理器会根据泛型类型处理事件
实现
@Component
public class EventHandler implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {//todo----System.out.println(event.getMsg());}
}
5 异步事件:
Spring默认监控的事件都是同步的,实现异步事件就需要开启异步事件的支持,配置类上使用@EventListener注解开启异步支持,然后在监听器上使用@Async注解标注即可,同一个事件多个处理器可以使用@Order注解进行排序(参数越小优先级越高)
实现:
@Configuration
@EnableAsync
public class EventConfig {@Async@EventListenerpublic void doWithEvent(MyEvent myEvent) {System.out.println("事件消息是: "+myEvent.getMsg());}
}@Async//配置类已经开启异步支持
@Component
public class EventHandler implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {//todo----System.out.println(event.getMsg());}
}
6 事件异常处理器(事件消费方出现异常进行必要处理)
(1) 同步的:
编写异常处理器实现 org.springframework.util.ErrorHandler
import org.springframework.stereotype.Component;
import org.springframework.util.ErrorHandler;//同步方式异常处理器
@Component
public class DoExphandler implements ErrorHandler {/*** 只要在SimpleApplicationEventMulticaster设置这个异常处理器,* 事件消费方抛出异常就会触发这个方法中的异常,SimpleApplicationEventMulticaster.setErrorHandler(exphandler);*/@Overridepublic void handleError(Throwable e) {if (e instanceof RuntimeException) {//todo} else {}}
}
在SimpleApplicationEventMulticaster事件广播中设置消费事的异常处理器
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {//实现方式一private ApplicationContext applicationContext;//实现方式二private ApplicationEventPublisher applicationEventPublisher;//事件推送类注入广播处理同步异常@Autowiredprivate SimpleApplicationEventMulticaster saem;@Autowiredprivate DoExphandler exphandler;/*** 容器初始化时候会自动的填装该对象** @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 容器初始化时候会自动的填装该对象** @param applicationEventPublisher*/@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}public void sentEvent2(Object msg) {applicationContext.publishEvent(new MyEvent2((String) msg));}/*** 设置初始化的事件异常处理器*/@PostConstructpublic void init(){saem.setErrorHandler(exphandler);}}
(2)异步的:
编写异步事件处理器异常类,实现AsyncUncaughtExceptionHandler接口
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {@Overridepublic void handleUncaughtException(Throwable ex,Method method,Object... params) {//todo,做相关处理ex.printStackTrace();}
}
做异步事件异常配置:
实现AsyncConfigurer接口
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;import java.util.concurrent.Executor;@Configuration
public class AsyncConfig implements AsyncConfigurer {@Autowiredprivate AsyncExceptionHandler asyncExceptionHandler;@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return asyncExceptionHandler;}@Overridepublic Executor getAsyncExecutor() {System.out.println("getAsyncExecutor");return AsyncConfigurer.super.getAsyncExecutor();}
}
7 java自带的事件:
(1)观察者模式:
作用: 解耦,解耦....其他都是废话
模式工作思想: a观察b,b做出某些动作后,a就及时的做动作的跟进(至于a做啥,看你需要他做啥)
设计思想:a根据b的状态变化做出响应,一般情况下都是多个对象观察一个对象,此时被观察者b就需要感知到都有哪些对象在观察自己(设置集合存储这些对象)
观察者:(在java.util.Observer已经做了顶层接口)
public interface MyObserver {void update(ObserverHandler handler);
}class MyObserverImp implements MyObserver{private int status;/*** 根据被观察者对象适应自身动作* @param handler 被观察者对象*/@Overridepublic void update(ObserverHandler handler) {status=((Handler)handler).getStatus();}
被观察者:(java.util. Observable已经做了适应)
interface ObserverHandler {//存储观察者,感知都有那些对象在观察List<MyObserver> list = new ArrayList<>();
}class Handler implements ObserverHandler {private int status;public void setStatus(int status) {this.status = status;updateAllStatus();}public int getStatus() {return status;}public void updateAllStatus() {for (MyObserver myObserver : list) {myObserver.update(this);}}public void addObserver(MyObserver observer) {list.add(observer);}public void removeObserver(MyObserver observer) {list.remove(observer);}
}
(2)java的事件:
创建事件继承java.util.EventObject
public class UserEvent extends EventObject {public UserEvent(Object source) {super(source);}
}class SendMessageEvent extends UserEvent {public SendMessageEvent(Object source) {super(source);}
}class SendFileEvent extends UserEvent {public SendFileEvent(Object source) {super(source);}
}
创建事件监听器继承:java.util.EventListener
interface UserListener extends EventListener {static final ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();void doWithEvent(UserEvent event);
}class Listener implements UserListener {@Overridepublic void doWithEvent(UserEvent event) {if (event instanceof SendFileEvent) {System.out.println(event);} else if (event instanceof SendMessageEvent) {System.out.println(event);}}
}
推送事件:
class SendEventHandler {private static UserListener listener = new Listener();public static void main(String[] args) {final SendMessageEvent sentMessage = new SendMessageEvent("发送事件");final SendFileEvent sendFile = new SendFileEvent("发送文件");listener.doWithEvent(sentMessage);listener.doWithEvent(sendFile);}
}
Spring的Event相关推荐
- EventBus VS Spring Event
EventBus VS Spring Event 本地异步处理,采用事件机制 可以使 代码解耦,更易读.事件机制实现模式是 观察者模式(或发布订阅模式),主要分为三部分:发布者.监听者.事件. Gua ...
- spring event的事件驱动模型的最佳实践@EventListener
文章目录 1.spring下使用event模型 1.1 定义event 1.2 event的监听处理类.监听类实现ApplicationListener 里onApplicationEvent方法即可 ...
- java spring eventbus_Spring 事件:Application Event
前言 想必你一定为两个 Bean 之间基于耗时事件处理的通知和处理顺序而困扰吧,有困扰没事,不要憋在肚子里,早已经有先驱们发现了痛点并设计出了解决方案--Application Event.(了解 A ...
- Spring Event + DDD = 王炸!!
点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...
- How those spring enable annotations work--转
原文地址:http://blog.fawnanddoug.com/2012/08/how-those-spring-enable-annotations-work.html Spring's Java ...
- Spring Data MongoDB级联保存在DBRef对象上
默认情况下, Spring Data MongoDB不支持对带有@DBRef注释的引用对象的级联操作,如引用所述 : 映射框架不处理级联保存 . 如果更改了Person对象引用的Account对象,则 ...
- @bean 什么时候执行_写好一个Spring组件的实现步骤是什么?
这篇文章主要介绍了如何写好一个Spring组件的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,希望可以帮助到大家! 本文详细的介绍了Spring组件的实现步骤, ...
- 浅析 Spring 中的事件驱动机制
今天来简单地聊聊事件驱动,其实写这篇文章挺令我挺苦恼的,因为事件驱动这个名词,我没有找到很好的定性解释,担心自己的表述有误,而说到事件驱动可能立刻联想到如此众多的概念:观察者模式,发布订阅模式,消息队 ...
- 依赖 netty spring_面试官:如何写好一个 Spring 组件?懵圈!
背景 Spring 框架提供了许多接口,可以使用这些接口来定制化 bean ,而非简单的 getter/setter 或者构造器注入.细翻 Spring Cloud Netflix.Spring Cl ...
最新文章
- 选择排序_在N + 1场景中,使用@NamedEntityGraph更有选择地加载JPA实体
- 大数据:Parquet文件存储格式
- python 批量增加文件前缀_用python批量提取视频中的音频文件
- messagebox java_如何从messagebox获得答案
- 【数据结构算法】数据结构思维导图
- 暴力猴加脚本的适当应用
- 计算机二级公共知识web,全国计算机等级考试二级web大纲
- 电力巡检系统无人机模块
- Mars-Android开发视频教程(全集)
- pdf.js 跨域 php,JavaScript_js跨域资源共享 基础篇,本文详细介绍了javascript跨域资 - phpStudy...
- 搭建STM32开发环境
- Java面试题(一) 题目:输入某年某月某日,判断这一天是这一年的第几天
- Java实现 LeetCode 37 解数独
- 如何删除联想lenovo硬盘的隐藏分区
- 【视频】2017,50个令人屏息的科技瞬间
- 关于C语言二级机考软件环境的一些问题
- 移动端滑动事件---实战笔记
- 最细RGB颜色表,建议收藏
- 中国南极科考队两支内陆小分队顺利“会师”
- 布隆,牛逼!布谷鸟,牛逼!