Spring 观察者模式详解以及自定义监听器扩展实现(下)

简介: Spring 观察者模式详解以及自定义监听器扩展实现(下)

SpringBoot 监听器加载过程

首先加载 META-INF/spring.factories 文件中的 key:ApplicationListener,value:全限定类名,然后获取到所有的实例存入 ApplicationContext 中,方便后续创建多播器对象时可以获取到这些监听器实例,注入:ApplicationContext 实例以后,就可以调用它来进行事件发布动作

通过观察以上内置监听器的源码,可以发现在这些监听器里都实现了 ApplicationListener 同时会使用到抽象类 ApplicationEvent,但这些内置监听器中的事件都是基于它抽象的实现,定义自己的事件类

事件驱动机制是基于观察者设计模式的实现,通过 ApplicationEvent 类、ApplicationListener 接口,可以通过 ApplicationContext 实现事件的发布

如下图整理了 SpringBoot 内置的监听器和事件:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

前戏: 在事件准备发布时,首先会通过 getRunListeners 方法来获取我们在 META-INF/spring.factories 文件中的定义 SpringApplicationRunListener 接口实现类 EventPublishingRunListener,同时会完成该类的实例化操作,调用构造方法时,会初始化多路广播器对象:SimpleApplicationEventMulticaster,同时从上下文获取到前面加载好的 11 个监听器,进行绑定操作.

前戏工作做完以后,就到了发布事件的时候了

SimpleApplicationEventMulticaster#multicastEvent:在容器启动时会调用 listener#starting 方法(事件名:ApplicationStartingEvent)、环境对象准备前会调用 listener#environmentPrepared(事件名:ApplicationEnvironmentPreparedEvent)

以 ConfigFileApplicationListener 为例,会在其内部处理配置文件的解析工作,接受 ApplicationEnvironmentPreparedEvent 事件的处理,源码如下:

public void onApplicationEvent(ApplicationEvent event) {
      if (event instanceof ApplicationEnvironmentPreparedEvent) {
          this.onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent)event);
      }
      if (event instanceof ApplicationPreparedEvent) {
          this.onApplicationPreparedEvent(event);
      }
  }

自定义监听器扩展实现

通过几个不同类型自定义事件案例来加深对事件驱动机制的理解

监听所有事件

先创建一个自定义监听器,来监听所有的事件;创建一个 Java 类,实现 ApplicationListener 接口在泛型中指定要监听的事件类型即可,如果要监听所有的事件,那么泛型就写 ApplicationEvent

public class MySpringApplicationListener implements ApplicationListener<ApplicationEvent> {
  @Override
  public void onApplicationEvent(ApplicationEvent event) {
    System.out.println("自定义监听器--->" + event);
  }
}

之后为了在容器启动中能够发现我们的监听器并且添加到 SimpleApplicationEventMulticaster 中,我们需要在 spring.factories/META-INF 中注册自定义的监听器

org.springframework.context.ApplicationListener=\
com.vnjohn.demo.listener.MySpringApplicationListener

这样当我们启动服务的时候就可以看到相关事件发布,我们的监听器被触发了,会打印对应的信息

监听特定事件

如果是监听特定的事件,我们只需要在泛型出指定类型即可

public class MySpringApplicationStartingListener implements ApplicationListener<ApplicationStartingEvent> {
  @Override
  public void onApplicationEvent(ApplicationStartingEvent event) {
    // 该事件是启动启动时就会进行发布的,查询容器启动日志信息即可 
    System.out.println("MySpringApplicationStartingListener--------->" + event);
  }
}
org.springframework.context.ApplicationListener=\
com.vnjohn.demo.listener.MySpringApplicationListener,\
com.vnjohn.demo.listener.MySpringApplicationStartingListener

启动服务时可以看到相关的事件发布

自定义事件

若我们想要通过自定义的监听器来监听自定义的事件呢?首先创建自定义的事件类,非常简单,只需要继承 ApplicationEvent 即可

public class MyEvent extends ApplicationEvent {
  public MyEvent(Object source) {
    super(source);
  }
}

然后在自定义的监听器中监听自定义的事件

public class MyCustomerEventListener implements ApplicationListener<MyEvent> {
  @Override
  public void onApplicationEvent(MyEvent event) {
    System.out.println("MyCustomerEventListener ---》自定义事件触发" + event);
    // 触发对应的事件后 业务处理
    new Thread(()->{
      // 业务....
    }).start();
  }
}

事件的监听和发布是同步执行的,如果想让其异步的进行,可以抛给一个线程进行处理

org.springframework.context.ApplicationListener=\
com.vnjohn.demo.listener.MySpringApplicationListener,\
com.vnjohn.demo.listener.MySpringApplicationStartingListener,\
com.vnjohn.demo.listener.MyCustomerEventListener

之后我们就可以在我们特定的业务场景中类发布对应的事件了

@Component
public class MyApplicationContextAware implements ApplicationContextAware {
  private static ApplicationContext applicationContext;
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    MyApplicationContextAware.applicationContext = applicationContext;
  }
  public static void publishEvent(ApplicationEvent applicationEvent) {
    applicationContext.publishEvent(applicationEvent);
  }
}
@RestController
public class HelloController {
  @GetMapping("/hello")
  public String hello(){
    MyApplicationContextAware.publishEvent(new MyEvent(new Object()));
    return "hello---";
  }
}

当提交请求后,对应的监听器就触发了,这样一来不光搞清楚了 SpringBoot 中的监听机制,而且也可以扩展使用到我们业务开发中了

总结

希望对你有所帮助,您的支持是对我最大的鼓励,关注+赞+收藏三连,感谢!

如果觉得博文不错,关注我 vnjohn,后续会有更多实战、源码、架构干货分享!

大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!

目录
相关文章
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
15122 60
|
Java 数据安全/隐私保护 微服务
微服务——SpringBoot使用归纳——Spring Boot中使用监听器——Spring Boot中自定义事件监听
本文介绍了在Spring Boot中实现自定义事件监听的完整流程。首先通过继承`ApplicationEvent`创建自定义事件,例如包含用户数据的`MyEvent`。接着,实现`ApplicationListener`接口构建监听器,用于捕获并处理事件。最后,在服务层通过`ApplicationContext`发布事件,触发监听器执行相应逻辑。文章结合微服务场景,展示了如何在微服务A处理完逻辑后通知微服务B,具有很强的实战意义。
761 0
|
缓存 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot中使用监听器——监听器介绍和使用
本文介绍了在Spring Boot中使用监听器的方法。首先讲解了Web监听器的概念,即通过监听特定事件(如ServletContext、HttpSession和ServletRequest的创建与销毁)实现监控和处理逻辑。接着详细说明了三种实际应用场景:1) 监听Servlet上下文对象以初始化缓存数据;2) 监听HTTP会话Session对象统计在线用户数;3) 监听客户端请求的Servlet Request对象获取访问信息。每种场景均配有代码示例,帮助开发者理解并应用监听器功能。
736 0
|
9月前
|
监控 安全 Java
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
Spring Boot 通过 Actuator 模块提供了强大的健康检查功能,帮助开发者快速了解应用程序的运行状态。默认健康检查可检测数据库连接、依赖服务、资源可用性等,但在实际应用中,业务需求和依赖关系各不相同,因此需要实现自定义健康检查来更精确地监控关键组件。本文介绍了如何使用 @HealthEndpoint 注解及实现 HealthIndicator 接口来扩展 Spring Boot 的健康检查功能,从而提升系统的可观测性与稳定性。
641 0
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
|
11月前
|
人工智能 安全 Java
Spring Boot 过滤器 拦截器 监听器
本文介绍了Spring Boot中的过滤器、拦截器和监听器的实现与应用。通过Filter接口和FilterRegistrationBean类,开发者可实现对请求和响应的数据过滤;使用HandlerInterceptor接口,可在控制器方法执行前后进行处理;利用各种监听器接口(如ServletRequestListener、HttpSessionListener等),可监听Web应用中的事件并作出响应。文章还提供了多个代码示例,帮助读者理解如何创建和配置这些组件,适用于构建更高效、安全和可控的Spring Boot应用程序。
910 0
|
前端开发 Java 数据库连接
Spring MVC 扩展和SSM框架整合
通过以上步骤,我们可以将Spring MVC扩展并整合到SSM框架中。这个过程包括配置Spring MVC和Spring的核心配置文件,创建控制器、服务层和MyBatis的Mapper接口及映射文件。在实际开发中,可以根据具体业务需求进行进一步的扩展和优化,以构建更加灵活和高效的企业级应用程序。
338 5
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
1097 1
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
Java Spring
Java Spring Boot监听事件和处理事件
通过上述步骤,我们可以在Java Spring Boot应用中实现事件的发布和监听。事件驱动模型可以帮助我们实现组件间的松耦合,提升系统的可维护性和可扩展性。无论是处理业务逻辑还是系统事件,Spring Boot的事件机制都提供了强大的支持和灵活性。希望本文能为您的开发工作提供实用的指导和帮助。
623 15
|
缓存 安全 Java
Spring高手之路26——全方位掌握事务监听器
本文深入探讨了Spring事务监听器的设计与实现,包括通过TransactionSynchronization接口和@TransactionalEventListener注解实现事务监听器的方法,并通过实例详细展示了如何在事务生命周期的不同阶段执行自定义逻辑,提供了实际应用场景中的最佳实践。
651 3
Spring高手之路26——全方位掌握事务监听器