Spring中的事件驱动模型(一)

您所在的位置:网站首页 springboot事件驱动 Spring中的事件驱动模型(一)

Spring中的事件驱动模型(一)

2023-08-23 06:18| 来源: 网络整理| 查看: 265

事件驱动模型

事件驱动模型通常也被理解成观察者或者发布/订阅模型。

是一种对象间的一对多的关系;当目标发送改变(发布),观察者(订阅者)就可以接收到改变;观察者如何处理,目标无需干涉,它们之间的关系是松耦合的。

event-source

事件驱动模型的例子很多,如生活中的红绿灯,以及我们在微服务中用到的配置中心,当有配置提交时出发具体的应用实例更新Spring上下文环境。

Spring的事件机制基本概念

Spring的事件驱动模型由三部分组成:

事件:ApplicationEvent,继承自JDK的EventObject,所有事件将继承它,并通过source得到事件源。事件发布者:ApplicationEventPublisher及ApplicationEventMulticaster接口,使用这个接口,我们的Service就拥有了发布事件的能力。事件订阅者:ApplicationListener,继承自JDK的EventListener,所有监听器将继承它。Spring事件驱动过程事件

Spring 默认对 ApplicationEvent 事件提供了如下实现:

ContextStoppedEvent:ApplicationContext停止后触发的事件;ContextRefreshedEvent:ApplicationContext初始化或刷新完成后触发的事件;ContextClosedEvent:ApplicationContext关闭后触发的事件。如web容器关闭时自动会触发Spring容器的关闭,如果是普通java应用,需要调用ctx.registerShutdownHook()注册虚拟机关闭时的钩子才行;ContextStartedEvent:ApplicationContext启动后触发的事件;

eventobject

1public abstract class ApplicationEvent extends EventObject { 2 private static final long serialVersionUID = 7099057708183571937L; 3 //事件发生的时间 4 private final long timestamp = System.currentTimeMillis(); 5 //创建一个新的ApplicationEvent事件 6 public ApplicationEvent(Object source) { 7 super(source); 8 } 9 10 public final long getTimestamp() { 11 return this.timestamp; 12 } 13}

事件基类ApplicationEvent,所有的具体事件都会继承该抽象事件类。

事件监听者

ApplicationListener

ApplicationListener继承自JDK的EventListener,JDK要求所有监听器将继承它。

1@FunctionalInterface 2public interface ApplicationListener extends EventListener { 3 void onApplicationEvent(E var1); 4}

提供了onApplicationEvent方法,用以处理ApplicationEvent,不过对于具体事件的处理需要进行判断。而GenericApplicationListener和SmartApplicationListener提供了关于事件更多的元数据信息。

1public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener { 2 3 private final Object source; 4 5 @Nullable 6 private GenericApplicationListener delegate; 7 8 //为特定事件源创建SourceFilteringListener,并传入代理的监听器类 9 public SourceFilteringListener(Object source, ApplicationListener delegate) { 10 this.source = source; 11 this.delegate = (delegate instanceof GenericApplicationListener ? 12 (GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate)); 13 } 14 //....省略部分代码 15 16 @Override 17 public int getOrder() { 18 return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE); 19 } 20 21 //过滤之后实际处理事件 22 protected void onApplicationEventInternal(ApplicationEvent event) { 23 //... 24 this.delegate.onApplicationEvent(event); 25 } 26 27}

SourceFilteringListener是ApplicationListener的装饰器类,过滤特定的事件源。只会注入其事件对应的代理监听器,还提供了按照顺序触发监听器等功能。 在启动的时候会加载一部分 ApplicationListener。Spring Context加载初始化完成(refresh)后会再次检测应用中的 ApplicationListener,并且注册,此时会将我们实现的 ApplicationListener 就会加入到 SimpleApplicationEventMulticaster 维护的 Listener 集合中。 Spring也支持直接注解的形式进行事件监听@EventListener(Event.class)。

事件发布

EventPublisher

ApplicationContext接口继承了ApplicationEventPublisher,并在AbstractApplicationContext实现了具体代码,实际执行是委托给ApplicationEventMulticaster。

1@FunctionalInterface 2public interface ApplicationEventPublisher { 3 //通知所有的注册该事件的应用,事件可以是框架事件如RequestHandledEvent或者特定的应用事件。 4 default void publishEvent(ApplicationEvent event) { 5 this.publishEvent((Object)event); 6 } 7 8 void publishEvent(Object var1); 9}

实际的执行是委托给,读者有兴趣可以看一下AbstractApplicationContext中这部分的逻辑。下面我们具体看一下ApplicationEventMulticaster接口中定义的方法。

1public interface ApplicationEventMulticaster { 2 3 //增加监听者 4 void addApplicationListener(ApplicationListener listener); 5 //... 6 7 //移除监听者 8 void removeApplicationListener(ApplicationListener listener); 9 //... 10 11 //广播特定事件给监听者 12 void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType); 13 14}

AbstractApplicationContext中定义了对监听者的操作维护,如增加和删除,并提供了将特定事件进行广播的方法。下面看一下具体实现类SimpleApplicationEventMulticaster。ApplicationContext自动到本地容器里找一个ApplicationEventMulticaster实现,如果没有则会使用默认的SimpleApplicationEventMulticaster。

1public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { 2 3 @Nullable 4 private Executor taskExecutor; 5 6 //... 7 8 //用给定的beanFactory创建SimpleApplicationEventMulticaster 9 public SimpleApplicationEventMulticaster(BeanFactory beanFactory) { 10 setBeanFactory(beanFactory); 11 } 12 13 @Override 14 public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { 15 ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); 16 for (final ApplicationListener listener : getApplicationListeners(event, type)) { 17 Executor executor = getTaskExecutor(); 18 if (executor != null) { 19 executor.execute(() -> invokeListener(listener, event)); 20 } 21 else { 22 invokeListener(listener, event); 23 } 24 } 25 } 26 27 //注入给定事件的给定监听器 28 protected void invokeListener(ApplicationListener listener, ApplicationEvent event) { 29 ErrorHandler errorHandler = getErrorHandler(); 30 if (errorHandler != null) { 31 try { 32 doInvokeListener(listener, event); 33 } 34 ... 35 } 36 else { 37 doInvokeListener(listener, event); 38 } 39 } 40 41 @SuppressWarnings({"unchecked", "rawtypes"}) 42 private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) { 43 try { 44 listener.onApplicationEvent(event); 45 } 46 //... 47 } 48 49}

在multicastEvent方法中,executor不为空的情况下,可以看到是支持异步发布事件。发布事件时只需要调用ApplicationContext中的publishEvent方法即可进行事件的发布。

总结

本文主要介绍了Spring中的事件驱动模型相关概念。首先介绍事件驱动模型,也可以说是观察者模式,在我们的日常生活中和应用开发中有很多应用。随后重点篇幅介绍了Spring的事件机制,Spring的事件驱动模型由事件、发布者和订阅者三部分组成,结合Spring的源码分析了这三部分的定义与实现。笔者将会在下一篇文章,结合具体例子以及Spring Cloud Config中的实现进行实战讲解。

参考事件驱动模型简介Spring事件驱动模型与观察者模式


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3