Spring 框架——事件驱动模型

目录

1.概述

(1)Spring 事件驱动模型 是 Spring 框架中的一种编程模型,也被称为发布/订阅模型 ,通过使用观察者模式事件机制 ,实现了组件之间基于事件的解耦和通信。在 Spring 中,事件驱动模型建立在应用上下文事件 (ApplicationContextEvent) 的基础上。应用上下文事件是一种用于描述应用状态改变的事件,如应用上下文初始化完成、上下文刷新、上下文关闭等。

(2)通过事件驱动模型,Spring 框架提供了更灵活、松散耦合的方式来实现组件之间的通信和解耦。开发者可以定义自己的事件,并通过事件监听器来处理,实现自定义的业务逻辑,扩展框架的行为,并能够更容易地实现可测试、可维护和可扩展的应用程序。

有关观察者模式的相关知识可以参考Java 设计模式------观察者模式

2.三种角色

2.1.事件角色

(1)事件是系统中发生的特定动作或者状态的表示。它可以是一个普通的 Java 对象,通常包含与该事件相关的数据和信息。例如,一个用户注册事件可以包含用户的姓名、邮箱等信息。

(2)在 Spring 中,org.springframework.context 包下的抽象类 ApplicationEvent 充当了事件的角色,它继承了 java.util.EventObject 类。并且Spring 中默认存在以下 4 种事件,它们都是继承了 ApplicationContextEvent 类(该类继承自 ApplicationEvent):

  • ContextClosedEvent:表示应用程序上下文关闭事件,触发时机是在应用程序上下文关闭时;
  • ContextRefreshedEvent:表示应用程序上下文刷新事件,触发时机是在应用程序上下文初始化及刷新完成后
  • ContextStartedEvent:表示应用程序上下文启动事件,触发时机是在应用程序上下文启动时;
  • ContextStoppedEvent:表示应用程序上下文停止事件,触发时机是在应用程序上下文停止时;

(3)上述类之间的关系如下图所示:

2.2.事件监听者角色

接口 ApplicationListener 充当了事件监听者角色,其源码如下所示。该接口中定义了一个名为 onApplicationEvent() 的方法来处理事件 ApplicationEvent。因此,在 Spring 中我们只需该接口的 onApplicationEvent() 方法即可完成监听事件。

java 复制代码
package org.springframework.context;

import java.util.EventListener;

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);
}

2.3.事件发布者角色

接口 ApplicationEventPublisher 充当了事件发布者角色,其源码如下所示。该接口中的 publishEvent() 方法的具体实现是在AbstractApplicationContext 类中,具体细节此处就不再过多描述,感兴趣的读者可以去阅读其源码。

java 复制代码
package org.springframework.context;

@FunctionalInterface
public interface ApplicationEventPublisher {
	default void publishEvent(ApplicationEvent event) {
		publishEvent((Object) event);
	}

	void publishEvent(Object event);
}

(2)在事件驱动模型中,发布者 (Publisher) 和订阅者 (Subscriber) 是模型的关键角色。发布者通过发布事件的方式进行通知,而订阅者通过订阅(订阅)事件的方式接收通知。发布者和订阅者之间的关系是松散耦合的,发布者不需要知道订阅者的具体细节,只需要发布事件,并由框架负责将事件传递给订阅者。

(3)在 Spring 框架中,应用上下文充当事件的发布者,而事件监听器 (Event Listener) 充当事件的订阅者。监听器可以通过实现 ApplicationListener 接口或使用 @EventListener 注解来订阅应用上下文事件。当事件被发布时,相应的监听器会接收到事件并执行相应的逻辑,实现事件驱动的编程。

3.示例

(1)使用 Spring 的事件驱动模型的一般步骤如下:

  • 定义事件:继承抽象类 ApplicationEvent,并且写相应的构造函数;
  • 定义事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法;
  • 定义事件发送者:发送者调用 ApplicationContext 中的 publishEvent 方法来发送事件消息;

(2)示例代码如下所示:

  • 首先,定义一个继承自 ApplicationEvent 的事件类 CustomEvent
java 复制代码
import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent {

   private String message;

   public CustomEvent(Object source, String message) {
      super(source);
      this.message = message;
   }

   public String getMessage() {
      return message;
   }
}
  • 接下来,创建一个实现了 ApplicationListener 的事件监听器 CustomEventListener
java 复制代码
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {
	@Override
	public void onApplicationEvent(CustomEvent customEvent) {
		String message = customEvent.getMessage();
		System.out.println("接收到的信息为: " + message);
	}
}
  • 然后,创建一个事件发布者 EventPublisher
java 复制代码
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

@Component
public class CustomPublisher {
	@Autowired
	private ApplicationContext applicationContext;
	
	public void publish(CustomEvent customEvent) {
		this.applicationContext.publishEvent(customEvent);
	}
}
  • 当调用 CustomPublisherpublish() 方法时,比如 customPublisher.publish("Hello, World!") ,控制台就会打印出:
java 复制代码
接收到的信息为: Hello, World!
相关推荐
智慧老师2 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
hanbarger3 小时前
mybatis框架——缓存,分页
java·spring·mybatis
龙少95436 小时前
【深入理解@EnableCaching】
java·后端·spring
啦啦右一12 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
荆州克莱15 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei15 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
火烧屁屁啦15 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
岁岁岁平安16 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
北辰浮光16 小时前
[spring]XML配置文件标签
xml·spring
ZSYP-S16 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring