Spring中自定义事件原理

简介: Spring中自定义事件原理
  1. Spring中所有的事件监听器实现ApplicationListener.onApplicationEvent(E event)方法
  2. Spring容器会在启动的过程中获取所有的监听器对象,并持有,当有事件被抛出时,就会轮询所有监听这个事件的监听器进行处理。

通过源码理解过程:

  protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
      ApplicationEvent applicationEvent;
      if (event instanceof ApplicationEvent) {
          applicationEvent = (ApplicationEvent) event;
      }
      else {
          //封装成applicationEvent
          applicationEvent = new PayloadApplicationEvent<>(this, event);
          if (eventType == null) {
              eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
          }
      }
      // Multicast right now if possible - or lazily once the multicaster is initialized
      if (this.earlyApplicationEvents != null) {
          //监听器在注册到容器之前累积的事件,监听器注册完成之后会消耗掉这些事件,并将earlyApplicationEvents置空
          this.earlyApplicationEvents.add(applicationEvent);
      }
      else {//进行事件广播
          getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
      }

      //将事件抛给父容器
      // Publish event via parent context as well...
      if (this.parent != null) {
          if (this.parent instanceof AbstractApplicationContext) {
              ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
          }
          else {
              this.parent.publishEvent(event);
          }
      }
  }

SimpleApplicationEventMulticaster事件广播器

  //广播事件
  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);
          }
      }
  }

  //处理事件
  private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
      //调用监听器的方法进行处理
      listener.onApplicationEvent(event);
  }
  1. 监听器的创建过程
    EventListenerMethodProcessor对象会在容器中的对象实例化完成后,会对有@EventListener注解的方法进行代理,并创建相应的监听器。

具体看EventListenerMethodProcessor.processBean()方法

protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {

    if (!this.nonAnnotatedClasses.contains(targetType)) {
        Map<Method, EventListener> annotatedMethods = null;
        try {
            //找到有@EventListener注解的方法
            annotatedMethods = MethodIntrospector.selectMethods(targetType,
                    (MethodIntrospector.MetadataLookup<EventListener>) method ->
                            AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
        }
        catch (Throwable ex) {
            // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
            if (logger.isDebugEnabled()) {
                logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
            }
        }
        if (CollectionUtils.isEmpty(annotatedMethods)) {
            this.nonAnnotatedClasses.add(targetType);
            if (logger.isTraceEnabled()) {
                logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
            }
        }
        else {
            // Non-empty set of methods
            ConfigurableApplicationContext context = getApplicationContext();
            //轮询所有监听的方法
            for (Method method : annotatedMethods.keySet()) {
                //轮询所有的EventListenerFactory
                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中。
                        context.addApplicationListener(applicationListener);
                        break;//监听器不能重复,避免多个监听器工厂都支持同一个事件处理方法(工厂是排过序的)
                    }
                }
            }
            ......
        }
    }
}
目录
相关文章
|
1月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
1月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
3月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
37 1
|
2月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
96 0
|
2月前
|
设计模式 监控 Java
解析Spring Cloud中的断路器模式原理
解析Spring Cloud中的断路器模式原理
|
1月前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
1月前
|
Java 程序员 数据库连接
女朋友不懂Spring事务原理,今天给她讲清楚了!
该文章讲述了如何解释Spring事务管理的基本原理,特别是针对女朋友在面试中遇到的问题。文章首先通过一个简单的例子引入了传统事务处理的方式,然后详细讨论了Spring事务管理的实现机制。
女朋友不懂Spring事务原理,今天给她讲清楚了!
|
20天前
|
Java Spring 供应链
Spring 框架事件发布与监听机制,如魔法风暴席卷软件世界,开启奇幻编程之旅!
【8月更文挑战第31天】《Spring框架中的事件发布与监听机制》介绍了Spring中如何利用事件发布与监听机制实现组件间的高效协作。这一机制像城市中的广播系统,事件发布者发送消息,监听器接收并响应。通过简单的示例代码,文章详细讲解了如何定义事件类、创建事件发布者与监听器,并确保组件间松散耦合,提升系统的可维护性和扩展性。掌握这一机制,如同拥有一把开启高效软件开发大门的钥匙。
33 0
|
3月前
|
XML 监控 Java
Spring框架的核心原理与应用实践
Spring框架的核心原理与应用实践
|
2月前
|
存储 设计模式 Java
Spring Boot中的事件溯源模式
Spring Boot中的事件溯源模式