Spring事件监听机制
Spring中的事件发布在技术市场中有广泛的应用场景,以下是一些常见的使用情况:
**1.异步处理:**Spring事件发布可以用于异步处理请求,例如在后台处理长时间运行的任务,以避免阻塞主线程。
**2.分布式系统:**在分布式系统中,Spring事件发布可以用于在不同节点间传递信息,例如在微服务架构中,不同服务可以通过事件发布和订阅来进行通信。
**3.系统监控:**Spring事件发布可以用于系统监控,例如在系统出现异常时发布事件,以便及时进行处理。
**4.业务流程管理:**在复杂的业务流程中,Spring事件发布可以用于各个环节之间的交互和协同。
**5.扩展性:**Spring事件发布提供了很好的扩展性,开发者可以根据需求自定义事件和事件监听器。
因此,Spring中的事件发布是非常值得使用的,它可以提高系统的灵活性、可维护性和性能。
Springg事件监听机制的本质是观察者模式的应用,包括事件、事件监听器、事件发布器等主要组件。 **事件(Event):**一个实现了ApplicationEvent类的对象,代表了应用程序中的某个特定事件。我们可以根据需要创建自定义事件,只要继承ApplicationEvent类并添加相关的属性和方法就可以了。 **事件监听器(Event Listener):**实现了ApplicationListener接口的对象,其中E表示监听器需要处理的事件类型。监听器可以通过onApplicationEvent(E event)方法处理接收到的事件。另外,也可以使用@EventListener注解简化事件监听器的实现 **事件发布器(Event Publisher):**事件发布器负责将事件发布给所有关注该事件的监听器。在Spring中,ApplicationEventPublisher接口定义了事件发布的基本功能,而ApplicationEventPublisherAware接口允许组件获取到事件发布器的引用。Spring的核心容器ApplicationContext实现了ApplicationEventPublisher接口,因此在Spring应用中,通常直接使用ApplicationContext作为事件发布器。
实例
1 创建自定义的事件,这里以登录后需要处理的事件LoginEvent为例
package com.example.notesexample.envent;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.context.ApplicationEvent;
/**
* @Description: 登录的事件
* @Author: 爱吃橙子的
* @Date: 2024/3/19
**/
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class LoginEvent<T> extends ApplicationEvent {
private T content;
public LoginEvent(Object source, T content) {
super(source);
this.content = content;
}
}
2 这里定义Springutil实现接口ApplicationContextAware,实现setApplicationContext方法,容器启动时会自动调用实现ApplicationContextAware类的setApplicationContext方法将ApplicationContext的引用传递进来
package com.example.notesexample.envent;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
/**
* @Description: 事件发布器 通过实现ApplicationContextAware ,
* 在spring容器启动时会调用setApplicationContext方法,
* 从而是该类拿到ApplicationContext的引用,发布事件调用ApplicationContext的publishEvent(ApplicationEvent event)方法
* @Author: 爱吃橙子的
* @Date: 2024/3/19
**/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static void publishEvent(ApplicationEvent event) {
applicationContext.publishEvent(event);
}
}
3 调用SpringUtil的publishEvent方法发布事件
package com.example.notesexample.envent;
import com.example.notesexample.pojo.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description:
* @Author: 爱吃橙子的
* @Date: 2024/3/19
**/
@RestController
@RequestMapping("/auth")
public class LoginController {
@PostMapping("/login")
public User login(@RequestBody User user) {
// 处理登录的逻辑 这里省略...
// 发布登录后处理事件
SpringUtil.publishEvent(new LoginEvent(new Object(), user));
return user;
}
}
4 定义事件的监听器 LoginEventListener实现接口ApplicationListener 或者采用注解@EventListener ,这两种方式都能监听到LoginEvent事件的发布
package com.example.notesexample.envent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* @Description: 实现ApplicationListener 监听ApplicationContext发布的LoginEvent事件
* @Author: 爱吃橙子的
* @Date: 2024/3/19
**/
@Slf4j
@Component
public class LoginEventListener implements ApplicationListener<LoginEvent> {
@Override
public void onApplicationEvent(LoginEvent t) {
log.info("登录事件的内容:{}", t);
}
}
@Slf4j
@Component
public class EventListenerAnnoation {
@EventListener(classes = LoginEvent.class)
public void onApplicationEvent(LoginEvent t) {
log.info("登录事件的内容:{}", t);
}
}
两种方式是能够同时触发的