Spring事件监听机制

2019-09-17 10:54:50来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Spring事件监听机制

前言

Spring中的事件机制其实就是设计模式中的观察者模式,主要由以下角色构成:

  1. 事件
  2. 事件监听器(监听并处理事件)
  3. 事件发布者(发布事件)

首先看一下监听器和发布者的接口定义

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
      void onApplicationEvent(E event);
  }
  
  public interface ApplicationEventPublisher {
    default void publishEvent(ApplicationEvent event) {
        publishEvent((Object) event);
    }
    void publishEvent(Object event);

}

事件流转流程

初始化事件广播器

看一下这个方法AbstractApplicationContext.refresh,在IOC源码解析那篇文章已经把这个方法分析完了,所以直接关注事件广播器和事件发布相关的逻辑即可


?public?void?refresh()?throws?BeansException, IllegalStateException {
????????synchronized?(this.startupShutdownMonitor) {
????????????// Prepare this context for refreshing.
????????????prepareRefresh();
?
????????????// Tell the subclass to refresh the internal bean factory.
????????????ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
?
????????????// Prepare the bean factory for use in this context.
????????????prepareBeanFactory(beanFactory);
?
????????????try?{
????????????????// Allows post-processing of the bean factory in context subclasses.
????????????????postProcessBeanFactory(beanFactory);
?
????????????????// Invoke factory processors registered as beans in the context.
????????????????invokeBeanFactoryPostProcessors(beanFactory);
?
????????????????// Register bean processors that intercept bean creation.
????????????????registerBeanPostProcessors(beanFactory);
?
????????????????// Initialize message source for this context.
????????????????initMessageSource();
?
????????????????// 初始化事件广播器
????????????????initApplicationEventMulticaster();
?
????????????????// Initialize other special beans in specific context subclasses.
????????????????onRefresh();
?
????????????????// Check for listener beans and register them.
????????????????registerListeners();
?
????????????????// Instantiate all remaining (non-lazy-init) singletons.
????????????????finishBeanFactoryInitialization(beanFactory);
?
????????????????// 发布事件
????????????????finishRefresh();
????????????}
?
????????????catch?(BeansException ex) {
????????????????logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
?
????????????????// Destroy already created singletons to avoid dangling resources.
????????????????destroyBeans();
?
????????????????// Reset 'active' flag.
????????????????cancelRefresh(ex);
?
????????????????// Propagate exception to caller.
????????????????throw?ex;
????????????}
????????}
}

protected?void?initApplicationEventMulticaster() {
????????ConfigurableListableBeanFactory beanFactory = getBeanFactory();
????????if?(beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
????????????this.applicationEventMulticaster =
????????????????????beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
????????????if?(logger.isDebugEnabled()) {
????????????????logger.debug("Using ApplicationEventMulticaster ["?+?this.applicationEventMulticaster +?"]");
????????????}
????????}
????????else?{
????????????this.applicationEventMulticaster =?new?SimpleApplicationEventMulticaster(beanFactory);
????????????beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,?this.applicationEventMulticaster);
????????????if?(logger.isDebugEnabled()) {
????????????????logger.debug("Unable to locate ApplicationEventMulticaster with name '"?+
????????????????????????APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
????????????????????????"': using default ["?+?this.applicationEventMulticaster +?"]");
????????????}
????????}
????}

可以看到如果没有自定义的事件广播器,默认是使用SimpleApplicationEventMulticaster

发布事件

发布事件是在bean的初始化之后的


????protected?void?finishRefresh() {
????????// Initialize lifecycle processor for this context.
????????initLifecycleProcessor();
?
????????// Propagate refresh to lifecycle processor first.
????????getLifecycleProcessor().onRefresh();
?
????????// 发布事件
????????publishEvent(new?ContextRefreshedEvent(this));
?
????????// Participate in LiveBeansView MBean, if active.
????????LiveBeansView.registerApplicationContext(this);
????}


public?void?publishEvent(ApplicationEvent event) {
????????Assert.notNull(event,?"Event must not be null");
????????if?(logger.isTraceEnabled()) {
????????????logger.trace("Publishing event in "?+ getDisplayName() +?": "?+ event);
????????}
????????//1. 获取到事件广播器,发布事件
????????getApplicationEventMulticaster().multicastEvent(event);
????????//2. 如果存在父容器,父容器也将发布事件
????????if?(this.parent !=?null) {
????????????this.parent.publishEvent(event);
????????}
????}

具体的发布逻辑在multicastEvent方法中


public?void?multicastEvent(final?ApplicationEvent event) {
????????//遍历执行listener,getApplicationListeners调用AbstractApplicationEventMulticaster父类方法
????????for?(final?ApplicationListener listener : getApplicationListeners(event)) {
????????????Executor executor = getTaskExecutor();
????????????if?(executor !=?null) {
????????????????executor.execute(new?Runnable() {
????????????????????@Override
????????????????????public?void?run() {
????????????????????????listener.onApplicationEvent(event);
????????????????????}
????????????????});
????????????}
????????????else?{
????????????????listener.onApplicationEvent(event);
????????????}
????????}
????}

可以看到也没啥特殊的,无非就是起个线程池去调用这些监听器的方法

而监听器的处理就看各个监听器的具体实现了


原文链接:https://www.cnblogs.com/zhixiang-org-cn/p/11531633.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:为何一个@LoadBalanced注解就能让RestTemplate拥有负载均衡的能

下一篇:玩转 Springboot 2 之热部署(DevTools)