前文回顾
前一篇文章讲了 Spring 中的事件驱动模型相关概念重点篇幅介绍了 Spring 的事件机制, Spring 的事件驱动模型由事件发布者和订阅者三部分组成, 结合 Spring 的源码分析了这三部分的定义与实现本文主要结合具体例子讲解 Spring 中的事件驱动笔者在写 Spring Cloud Bus 中的事件的订阅与发布两篇文章的时候, 想到要把 Spring 中的事件驱动模型的讲解给补充一下, 这块也是属于更加基础的知识点
应用 Spring 中的事件驱动模式
我们示例配置信息的刷新, 当配置服务器收到提交的配置事件之后, 将会触发各个服务响应的更新自己的配置具体代码如下:
事件
- public class ConfigRefreshEvent extends ApplicationEvent {public ConfigRefreshEvent(final String content) {
- super(content);
- }
- }
定义一个配置刷新的事件继承 ApplicationEvent 即可, content 即为需要传递的 object
定义监听器
定义两个服务, 都实现了
SmartApplicationListener
, 该接口继承自
ApplicationListener
和 Ordered 接口, 属于标准监听器的扩展接口, 公开更多的元数据, 例如支持的事件类型和可排序的监听器
- public interface SmartApplicationListener extends ApplicationListener <ApplicationEvent> ,
- Ordered {
- /**
- * 决定该监听器是否支持给定的事件
- */
- boolean supportsEventType(Class <?extends ApplicationEvent> eventType);
- /**
- * 决定该监听器是否支持给定的目标类型, 支持才会调用
- */
- boolean supportsSourceType(Class <?>sourceType);
- }
下面贴出两个 Service 的代码
- ServiceAListener
- @Component
- public class ServiceAListener implements SmartApplicationListener {
- @Override
- public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
- return eventType == ConfigRefreshEvent.class;
- }
- @Override
- public boolean supportsSourceType(final Class<?> sourceType) {
- return sourceType == String.class;
- }
- @Override
- public void onApplicationEvent(final ApplicationEvent event) {
- System.out.println("ServiceA 收到新的配置:" + event.getSource());
- }
- @Override
- public int getOrder() {
- return Ordered.HIGHEST_PRECEDENCE;
- }
- }
- ServiceBListener
- @Component
- public class ServiceBListener implements SmartApplicationListener {
- @Override
- public boolean supportsEventType(final Class<? extends ApplicationEvent> eventType) {
- return eventType == ConfigRefreshEvent.class;
- }
- @Override
- public boolean supportsSourceType(final Class<?> sourceType) {
- return sourceType == String.class;
- }
- @Override
- public void onApplicationEvent(final ApplicationEvent event) {
- System.out.println("ServiceB 收到新的配置:" + event.getSource());
- }
- @Override
- public int getOrder() {
- return Ordered.LOWEST_PRECEDENCE;
- }
- }
测试类
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class ApplicationTest {
- @Autowired
- private ApplicationContext applicationContext;
- @Test
- public void testPublishEvent() {
- System.out.println("发布配置更新:");
- ConfigRefreshEvent event = new ConfigRefreshEvent("配置信息更新了")
- applicationContext.publishEvent(event);
- }
- }
上面是我们的测试类, 相当于事件的发布者, 首先定义一个配置刷新的事件, 然后通过注入的 ApplicationContext 发布该事件
由于 ServiceA 的优先级高于 ServiceB, 所以我们看到如下的结果:
发布配置更新:
ServiceA 收到新的配置: 配置信息更新了
ServiceB 收到新的配置: 配置信息更新了
总结
本文比较简单, 在上一篇介绍 Spring 中的事件驱动模型基础上, 具体应用到配置刷新的场景中 Spring 的事件驱动模型使用的是观察者模式通过 ApplicationEvent 抽象类和
ApplicationListener
接口, 可以实现事件的定义与监听, ApplicationContext 则实现了事件的发布例子中使用的
SmartApplicationListener
扩展了标准的事件监听接口, 监听器在处理 Event 时, 可以对传入的 Event 进行判断, 并且可以设定监听器的优先级后面抽时间会写一下 Spring Cloud 的热更新机制, 也是基于 Spring 中的事件驱动模型
来源: https://juejin.im/post/5aabc726f265da23870e98c7