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;//监听器不能重复,避免多个监听器工厂都支持同一个事件处理方法(工厂是排过序的)
                    }
                }
            }
            ......
        }
    }
}
目录
相关文章
|
8天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
19 0
|
3月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
3月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
4月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
119 0
|
4月前
|
设计模式 监控 Java
解析Spring Cloud中的断路器模式原理
解析Spring Cloud中的断路器模式原理
|
1月前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
128 9
|
1月前
|
XML 前端开发 Java
拼多多1面:聊聊Spring MVC的工作原理!
本文详细剖析了Spring MVC的工作原理,涵盖其架构、工作流程及核心组件。Spring MVC采用MVC设计模式,通过DispatcherServlet、HandlerMapping、Controller和ViewResolver等组件高效处理Web请求。文章还探讨了DispatcherServlet的初始化和请求处理流程,以及HandlerMapping和Controller的角色。通过理解这些核心概念,开发者能更好地构建可维护、可扩展的Web应用。适合面试准备和技术深挖
43 0
|
1月前
|
负载均衡 Java API
Spring Cloud原理详解
Spring Cloud原理详解
69 0
|
1月前
|
负载均衡 Java 网络架构
Spring Cloud原理详解
介绍了Spring Cloud的原理和核心组件,包括服务注册与发现、配置管理、负载均衡、断路器、智能路由、分布式消息传递、分布式追踪和服务熔断等,旨在帮助开发人员快速构建和管理微服务架构中的分布式系统。
56 0
下一篇
无影云桌面