Spring之事件机制详解,程序员进阶

在观察者模式中,一定要有一个管理维护监听者列表的功能。在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);

    }

    


# 面试结束复盘查漏补缺

每次面试都是检验自己知识与技术实力的一次机会,面试结束后建议大家及时总结复盘,查漏补缺,然后有针对性地进行学习,既能提高下一场面试的成功概率,还能增加自己的技术知识栈储备,可谓是一举两得。

**以下最新总结的阿里P6资深Java必考题范围和答案**,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

**重要的事说三遍,关注+关注+关注!**

![历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer](https://img-blog.csdnimg.cn/img_convert/6f30479c1848c32237c8119c5cc4945a.png)

![image.png](https://img-blog.csdnimg.cn/img_convert/1615fae90471a682ea77aeb21687caf5.png)



**更多笔记分享**

下最新总结的阿里P6资深Java必考题范围和答案**,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

**重要的事说三遍,关注+关注+关注!**

[外链图片转存中...(img-fEgc1Hqo-1630916338746)]

[外链图片转存中...(img-2Yh2wlDV-1630916338748)]



**更多笔记分享**

![历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer](https://img-blog.csdnimg.cn/img_convert/80c213c690bd5aa94c079377aa5e1a95.png)

你可能感兴趣的:(程序员,spring,面试,java,后端)