关于java:Spring-事件机制

41次阅读

共计 3675 个字符,预计需要花费 10 分钟才能阅读完成。

概念

在一个残缺的事件体系中、存在以下的角色

  1. 事件:形容产生了什么事件、比如说申请解决实现、Spring 容器刷新结束
  2. 事件源:事件的产生者、任何一个事件都必须有一个事件源。比方申请解决实现的事件源就是 DispatcherServlet、Spring 容器刷新结束的事件源就是 ApplicationContext
  3. 事件播送器:事件和事件监听器的桥梁、负责把事件告诉给事件监听器
  4. 事件监听器:监听事件的产生、能够在监听器中做一些解决

Spring 事件

咱们常见的事件可能就是 ApplicationContextEvent、它的子类 ContextRefreshedEvent 是咱们常见的事件类型、在 Spring 将所有非提早加载的 bean 实例化之后公布。

再来看看 Spring 事件的体系结构

Spring 监听器

事件播送器

ApplicationContext 对事件的反对

ApplicationEventPublisher 这个是 Spring 提供给用户应用的一个事件公布器啊、真正实现公布性能还是委托给下面的 ApplicationEventMulticaster 去实现的。

Spring 提供了 ApplicationEventPublisherAware 让用户能够去获取这个公布器进行事件公布。

应用形式

Spring 提供了两种形式

  1. 实现 ApplicationListener 接口
  2. 应用注解 @EventListener

注解的实现源码

咱们间接看到 EventListenerMethodProcessor 该类实现了接口 SmartInitializingSingleton 接口、该接口会在 Spring 初始化完所有的非提早加载的 bean 之后被调用。

public interface SmartInitializingSingleton {

   /**
    * Invoked right at the end of the singleton pre-instantiation phase,
    * with a guarantee that all regular singleton beans have been created
    * already. {@link ListableBeanFactory#getBeansOfType} calls within
    * this method won't trigger accidental side effects during bootstrap.
    * <p><b>NOTE:</b> This callback won't be triggered for singleton beans
    * lazily initialized on demand after {@link BeanFactory} bootstrap,
    * and not for any other bean scope either. Carefully use it for beans
    * with the intended bootstrap semantics only.
    */
   void afterSingletonsInstantiated();}

其实实现逻辑非常简单

for (Method method : annotatedMethods.keySet()) {for (EventListenerFactory factory : factories) {if (factory.supportsMethod(method)) {Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
         ApplicationListener<?> applicationListener =
               factory.createApplicationListener(beanName, targetType, methodToUse);
         if (applicationListener instanceof ApplicationListenerMethodAdapter) {((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
         }
         context.addApplicationListener(applicationListener);
         break;
      }
   }
}

找出所有被注解润饰的办法、而后别离创立一个对应的 ApplicationListener、收到事件后反射调用该办法。

public void processEvent(ApplicationEvent event) {Object[] args = resolveArguments(event);
   if (shouldHandle(event, args)) {Object result = doInvoke(args);
      if (result != null) {handleResult(result);
      }
      else {logger.trace("No result object given - no result to handle");
      }
   }
}

监听器调用的先后顺序

咱们能够在 AbstractApplicationEventMulticaster#retrieveApplicationListeners 中看到是反对咱们指定监听器的程序的、Spring 很多波及程序的都能够应用

  1. 实现 Ordered 接口
  2. 实现 PriorityOrdered 接口
  3. 应用 @Ordered 接口

异步调用监听器

默认状况下、Spring 创立的事件播送器是采纳同步形式调用告诉监听器的、咱们能够设置或者替换 Spring 默认的监听器来达到异步调用的目标、当然也能够扩大、依据事件的不同采纳同步或者异步的形式、而不是繁多的要么所有同步要么所有异步

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   Executor executor = getTaskExecutor();
   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {if (executor != null) {executor.execute(() -> invokeListener(listener, event));
      }
      else {invokeListener(listener, event);
      }
   }
}

Spring refresh 之前回初始化事件流传器

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.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isTraceEnabled()) {
         logger.trace("No'" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "'bean, using" +
               "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
      }
   }
}

替换原来的事件流传器

@Component("applicationEventMulticaster")
public class TestEventMulticaster extends SimpleApplicationEventMulticaster {}

正文完
 0