ApplicationEventMulticaster类:
在观察者模式中,一定要有一个管理维护监听者列表的功能。在Spring的事件机制中,将维护监听者列表的功能单独定义了一个接口,即ApplicationEventMulticaster接口。这也体现了单一责任原则的设计思想。我们看其源码:
public interface ApplicationEventMulticaster {
/**
-
Add a listener to be notified of all events.
-
@param listener the listener to add
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
-
Add a listener bean to be notified of all events.
-
@param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
-
Remove a listener from the notification list.
-
@param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
-
Remove a listener bean from the notification list.
-
@param listenerBeanName the name of the listener bean to remove
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
-
Remove all listeners registered with this multicaster.
-
After a remove call, the multicaster will perform no action
-
on event notification until new listeners are registered.
*/
void removeAllListeners();
/**
-
Multicast the given application event to appropriate listeners.
-
Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}
-
if possible as it provides better support for generics-based events.
-
@param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
/**
-
Multicast the given application event to appropriate listeners.
-
If the {@code eventType} is {@code null}, a default type is built
-
based on the {@code event} instance.
-
@param event the event to multicast
-
@param eventType the type of event (can be {@code null})
-
@since 4.2
*/
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
可以看到,这个接口定义了增删查监听者的方法,所以,监听者列表的维护通过这个接口实现。需要注意的是这个接口还定义了multicastEvent方法。通过这个方法,将事件传给监听器。所以这个类,将事件和监听器,连接在一起。这里采用的是中介者模式,这个接口就是中介者角色。
ApplicationEventPublisher:
Spring设计的事件发布类,我们看其源码:
public interface ApplicationEventPublisher {
/**
-
Notify all matching listeners registered with this
-
application of an application event. Events may be framework events
-
(such as ContextRefreshedEvent) or application-specific events.
-
Such an event publication step is effectively a hand-off to the
-
multicaster and does not imply synchronous/asynchronous execution
-
or even immediate execution at all. Event listeners are encouraged
-
to be as efficient as possible, individually using asynchronous
-
execution for longer-running and potentially blocking operations.
-
@param event the event to publish
-
@see #publishEvent(Object)
-
@see org.springframework.context.event.ContextRefreshedEvent
-
@see org.springframework.context.event.ContextClosedEvent
*/
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
/**
-
Notify all matching listeners registered with this
-
application of an event.
-
If the specified {@code event} is not an {@link ApplicationEvent},
-
it is wrapped in a {@link PayloadApplicationEvent}.
-
Such an event publication step is effectively a hand-off to the
-
multicaster and does not imply synchronous/asynchronous execution
-
or even immediate execution at all. Event listeners are encouraged
-
to be as efficient as possible, individually using asynchronous
-
execution for longer-running and potentially blocking operations.
-
@param event the event to publish
-
@since 4.2
-
@see #publishEvent(ApplicationEvent)
-
@see PayloadApplicationEvent
*/
void publishEvent(Object event);
}
里面定义了publishEvent方法,进行事件的发布。但是事件不是直接发布到listener中,而是发布在ApplicationEventMulticaster类中,所以在ApplicationEventPublisher类中,一定会有ApplicationEventMulticaster对象,将事件发布到ApplicationEventMulticaster中。
事件流程总结:
通过上面几个类的描述,我们总结一下spring事件机制的流程:
流程的核心,就是PublishEvent。Event对象以参数的形式传入PublishEvent对象。然后将Event事件传入ApplicationEventMulticaster类中,由ApplicationEventMulticaster类将事件传给其维护的监听者,执行监听者方法。
由上面Spring设计事件模式思路我们可以感受到,Spring把单一的功能,都拎出来形成了一套接口规范,然后多个接口规范组合,去完成一件事情。所以我们在阅读源码时会感觉很乱。只要我们分析清楚每个对象的设计思路和作用是什么,再分析他们之间的组合完成了什么事情,就很容易理解其设计理念了。
上面分析了Spring事件机制的运行原理,那么对我们实际开发中,有何帮助呢?
这就需要我们结合源码进行解读了。
笔者找到一篇写的很好的博文,大家可以参考:浅谈Spring事件监听。
我们可以自定义事件源,如下:
@Component
public class MyEventSource {
public void ccc(){
System.out.println(“事件源方法”);
}
}
然后定义Event对象,包装事件源:
@Component
public class MyEvent extends ApplicationEvent {
public MyEvent(MyEventSource source) {
super(source);
}
public void eventMethod(){
System.out.println(“事件自定义方法”);
}
}
这里我们需要注意,有参构造中,传入事件源,我们还可以在事件类中定义其他的方法,在监听者中调用。因为监听者监听的是事件类,所以可以直接调到事件类的自定义方法。
下面,我们定义监听者:
@Component
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/87bd60f2bf00620e7353a4b8f66ed5c9.jpeg)
独家面经总结,超级精彩
本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!
Java面试准备
准确的说这里又分为两部分:
- Java刷题
- 算法刷题
Java刷题:此份文档详细记录了千道面试题与详解;
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
-1713473473897)]
[外链图片转存中…(img-lk6ROdvv-1713473473898)]
Java面试准备
准确的说这里又分为两部分:
- Java刷题
- 算法刷题
Java刷题:此份文档详细记录了千道面试题与详解;
[外链图片转存中…(img-jY1iBWkM-1713473473898)]
[外链图片转存中…(img-FkjAB18w-1713473473898)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!