Spring 事件机制
1.前言
在springBoot 读取application.yml 一文中,曾经提到了用到了事件模式来触发读取application.yml.接下来讲解下spring的事件机制。spring事件机制其本质是JDK提供的事件机制的应用,利用的是观察者设计模式。
2.事件机制讲解
2.1关键概念
1.事件源
事件的触发者,比如上面的注册器就是事件源。对应ApplicationEventPublisher的实现类
2.事件
描述发生了什么事情的对象,比如上面的:xxx注册成功的事件。对应ApplicationEvent的实现类
3.事件监听器
监听到事件发生的时候,做一些处理。对应ApplicationListener的实现类
2.2实现流程
1.定义事件 如图:通过继承ApplicationEvent
2.定义publisher
方式1:通过实现ApplicationEventPublisherAware接口
方式2:直接注入ApplicationEventPublisher
3.定义listener 通过实现ApplicationListener
4.发布事件,触发监听器接收事件,处理事件
2.3实现原理
猜想一下,应该是在spring项目启动后,调用publisher的publishEvent方法,然后再调用了listener的onApplicationEvent.这样实现触发事件-->接收事件--->处理事件
1.AnnotationConfigApplicationContext实现了ApplicationEventPublisher,在我们自定义的publisher中注入的publisher就是AnnotationConfigApplicationContext。
2.调用自定义publisher调用publisherEvent,其实在调用AnnotationConfigApplicationContext在其父类AbstractApplicationContext的publishEvent方法。可以看到通过ApplicationEventMulticaster的multicastEvent发布了事件。
protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); Object applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent)event; } else { applicationEvent = new PayloadApplicationEvent(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType(); } } if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType); } if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext)this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
3.ApplicationEventMulticaster针对监听器做了维护工作,并负责发布事件。
public interface ApplicationEventMulticaster { void addApplicationListener(ApplicationListener<?> listener); void addApplicationListenerBean(String listenerBeanName); void removeApplicationListener(ApplicationListener<?> listener); void removeApplicationListenerBean(String listenerBeanName); void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate); void removeApplicationListenerBeans(Predicate<String> predicate); void removeAllListeners(); void multicastEvent(ApplicationEvent event); void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType); }
4.在ApplicationEventMulticaster实现类(默认SimpleApplicationEventMulticaster)中multicastEvent方法中获取到监听器,然后调用各个监听器的onWebApplicationEvent方法,以此实现事件的发布,监听,处理。
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步