Spring中的事件驱动模型(二)
前文回顾
前一篇文章讲了Spring中的事件驱动模型相关概念。重点篇幅介绍了Spring的事件机制,Spring的事件驱动模型由事件、发布者和订阅者三部分组成,结合Spring的源码分析了这三部分的定义与实现。本文主要结合具体例子讲解Spring中的事件驱动。笔者在写Spring Cloud Bus中的事件的订阅与发布两篇文章的时候,想到要把Spring中的事件驱动模型的讲解给补充一下,这块也是属于更加基础的知识点。
应用Spring中的事件驱动模式
我们示例配置信息的刷新,当配置服务器收到提交的配置事件之后,将会触发各个服务响应的更新自己的配置。具体代码如下:
事件
1public class ConfigRefreshEvent extends ApplicationEvent {
2 public ConfigRefreshEvent(final String content) {
3 super(content);
4 }
5}
定义一个配置刷新的事件。继承ApplicationEvent
即可,content即为需要传递的object。
定义监听器
定义两个服务,都实现了SmartApplicationListener
,该接口继承自ApplicationListener
和Ordered
接口,属于标准监听器的扩展接口,公开更多的元数据,例如支持的事件类型和可排序的监听器。
1public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
2
3 /**
4 * 决定该监听器是否支持给定的事件
5 */
6 boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
7
8 /**
9 * 决定该监听器是否支持给定的目标类型,支持才会调用
10 */
11 boolean supportsSourceType(Class<?> sourceType);
12
13}
下面贴出两个Service的代码。
ServiceAListener
1@Component
2public class ServiceAListener implements SmartApplicationListener {
3
4 @Override
5 public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
6 return eventType == ConfigRefreshEvent.class;
7 }
8
9 @Override
10 public boolean supportsSourceType(final Class<?> sourceType) {
11 return sourceType == String.class;
12 }
13
14 @Override
15 public void onApplicationEvent(final ApplicationEvent event) {
16 System.out.println("ServiceA收到新的配置:" + event.getSource());
17 }
18
19 @Override
20 public int getOrder() {
21 return Ordered.HIGHEST_PRECEDENCE;
22 }
23}
ServiceBListener
1@Component
2public class ServiceBListener implements SmartApplicationListener {
3
4 @Override
5 public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
6 return eventType == ConfigRefreshEvent.class;
7 }
8
9 @Override
10 public boolean supportsSourceType(final Class<?> sourceType) {
11 return sourceType == String.class;
12 }
13
14 @Override
15 public void onApplicationEvent(final ApplicationEvent event) {
16 System.out.println("ServiceB收到新的配置:" + event.getSource());
17 }
18
19 @Override
20 public int getOrder() {
21 return Ordered.LOWEST_PRECEDENCE;
22 }
23}
测试类
1@RunWith(SpringRunner.class)
2@SpringBootTest
3public class ApplicationTest {
4 @Autowired
5 private ApplicationContext applicationContext;
6
7 @Test
8 public void testPublishEvent() {
9 System.out.println("发布配置更新:");
10 ConfigRefreshEvent event = new ConfigRefreshEvent("配置信息更新了")
11 applicationContext.publishEvent(event);
12 }
13}
上面是我们的测试类,相当于事件的发布者,首先定义一个配置刷新的事件,然后通过注入的ApplicationContext
发布该事件。
由于ServiceA的优先级高于ServiceB,所以我们看到如下的结果:
1发布配置更新:
2ServiceA收到新的配置:配置信息更新了
3ServiceB收到新的配置:配置信息更新了
总结
本文比较简单,在上一篇介绍Spring中的事件驱动模型基础上,具体应用到配置刷新的场景中。Spring的事件驱动模型使用的是观察者模式。通过ApplicationEvent
抽象类和ApplicationListener
接口,可以实现事件的定义与监听,ApplicationContext
则实现了事件的发布。例子中使用的SmartApplicationListener
扩展了标准的事件监听接口,监听器在处理Event时,可以对传入的Event进行判断,并且可以设定监听器的优先级。后面抽时间会写一下 Spring Cloud 的热更新机制,也是基于Spring中的事件驱动模型。
- Spark监控官方文档学习笔记
- Bootstrap源码分析之nav、collapse
- Maven打包排除某个资源或者目录
- c/c++ 宏中"#"和"##"的用法
- 源码中的哲学——通过构建者模式创建SparkSession
- 长连接和短连接分析
- 基于编辑距离来判断词语相似度方法(scala版)
- 运算符优先级
- 腾讯云联手腾讯安全玄武实验室,提供「应用克隆」漏洞免费检测服务
- 1.注册或登录页面设计:UILabel,UIButton,UITextField
- 和为S的两个数字VS和为s的连续正数序列
- HANDLE
- Kafka的基本概念与安装指南(单机+集群同步)
- 科技专栏:001 机器人为美国带来大量失业人口,我们怎么办?
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 线程池的execute方法和submit方法有什么区别?
- os.mkdir()
- Java自动化测试(Jmeter 12)
- python剪切文件
- 设计模式(一):Android 源码中的单例模式
- Flask(数据库操作 十一)
- Golang | 既是接口又是类型,interface是什么神仙用法?
- 剑指offer第11题:机器人运动范围
- SQL 查找是否"存在",别再 count 了,很耗费时间的!
- 【LeeCode 中等 字节 python3】567. 字符串的排列
- Spark实现WordCount的几种方式总结
- Redis6之pub/sub发布与订阅(对比List和Kafka)
- SpringBoot原理?属性配置?在这里
- 【LeeCode 中等 矩阵】面试题 01.07. 旋转矩阵
- pytest文档44-allure.dynamic动态生成用例标题