spring事件监听
-
Spring中的事件监听器
一 概念 -
Spring中的事件监听
在一个Spring容器中,我们可以发送消息给Spring容器,容器收到消息后自动接受消息并进行处理
事件监听主要有两部分组成,一个是事件源,另一个是监听事件并处理的对象
使用的时候,我们只需要自定义事件继承事件对象ApplicationEvent,自定义监听器实现监听器ApplicationListener,并将监听器注册到Spring容器中即可
1.1 事件
Spring事件对象为ApplicationEvent,继承自ObjectEvent
public abstract class ApplicationEvent extends EventObject {
/**
* Create a new ApplicationEvent.
* 创建一个新的应用事件对象
* @param source the object on which the event initially occurred (never {@code null})
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
}
1.2 事件监听器
当事件对象被发布到Spring中的监听器,将会找出对应的监听器对事件进行处理
Spring中的事件监听器为ApplicationListener,继承自EventListener
public interface ApplicationListener
void onApplicationEvent(E var1);
}
二. Spring使用方式
创建事件对象
public class MyApplicationEvent extends ApplicationEvent {
public MyApplicationEvent(Object source) {
super(source);
}
}
创建监听器
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("收到事件:" + event);
}
}
注册监听器
public class ApplicationEventBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
// 注册自定义事件监听器
context.addApplicationListener(new MyApplicationListener());
// 启动上下文
context.refresh();
// 发布事件
context.publishEvent(new MyApplicationEvent(context));
// 结束
context.close();
}
三 SpringBoot中的推荐使用方式
- 事件对象继承ApplicationEvent、事件监听器实现ApplicationListener
举例:浙商资产管理中预警事件
Event
public class WarningEvent extends ApplicationEvent {
private Map<String,String> content;
/**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public WarningEvent(Object source) {
super(source);
}
public WarningEvent(Object source, Map<String,String> content) {
super(source);
this.content = content;
}
public Map<String,String> getContent() {
return content;
}
public void setContent( Map<String,String> content) {
this.content = content;
}
}
Listener
@Slf4j
@Component // 将监听器交给Spring容器管理
public class WarningListener implements ApplicationListener
@Override
public void onApplicationEvent(WarningEvent event) {
// do something
}
}
Test:伪代码,重点在于使用WebApplicationContext容器发布消息
@Component
public class TestEvent{
@Autowired
private WebApplicationContext webApplicationContext;
Map<String,String> params3 = new HashMap<>();
params3.put("deviceName",deviceName);
params3.put("deviceSerial",deviceSerial);
params3.put("url",picUrl);
params2.put("url",picUrl);
WarningEvent event = new WarningEvent("object",params3);
webApplicationContext.publishEvent(event);
}
- 使用@EventListener注解实现
实现方式:
自定义Event事件对象继承ApplicationEvent
使用类似BeanConfig类的方式,用@EventListener注解声明监听器
事件对象
public class WarningEvent extends ApplicationEvent {
private Map<String,String> content;
/**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public WarningEvent(Object source) {
super(source);
}
public WarningEvent(Object source, Map<String,String> content) {
super(source);
this.content = content;
}
public Map<String,String> getContent() {
return content;
}
public void setContent( Map<String,String> content) {
this.content = content;
}
}
注册监听器
@Component // 也要把该类交给Spring容器管理
public class ListenerConfig{
@Listener(WarningEvent.class) // 标明监听的哪个事件
public void onEvent(WarnEvent event){
Object source = event.getSouce();
// do something
}
发布事件
-
@Component public class TestEvent{ @Autowired private WebApplicationContext webApplicationContext; Map<String,String> params3 = new HashMap<>(); params3.put("deviceName",deviceName); params3.put("deviceSerial",deviceSerial); params3.put("url",picUrl); params2.put("url",picUrl); WarningEvent event = new WarningEvent("object",params3); webApplicationContext.publishEvent(event); }
-
使用ConfigurableApplicationContext装载监听
public class MyListener1 implements ApplicationListener<MyEvent>{
Logger logger = Logger.getLogger(MyListener1.class);
public void onApplicationEvent(MyEvent event)
{
logger.info(String.format("%s监听到事件源:%s.", MyListener1.class.getName(), event.getSource()));
}
}
@SpringBootApplication
public class LisenterApplication
{
public static void main(String[] args)
{
ConfigurableApplicationContext context = SpringApplication.run(LisenterApplication.class, args);
//装载监听,完成
context.addApplicationListener(new MyListener1());
}
}
----------------------------------------------------------------------------------------------------------
在Spring Framwork框架中关于事件分为两类, 一类是官方提供的标准事件, 一类是用户自定义事件
标准事件
官方文档上提供了6个标准事件
ContextRefreshedEvent
在已初始化或刷新ApplicationContext后发布该事件, 在该事件发生时, ApplicationContext中所有的bean都已经加载并激活.
ContextStartedEvent
在ConfigurableApplicationContext接口上使用start()方法启动ApplicationContext, 并且在ApplicationContext启动后发布事件。在这里,"启动后"意味着所有生命周中的bean接收到启动的显示通知。通常,此信号用于在显式停止后重新启动Bean,但也可以用于启动尚未配置为自动启动的组件(例如,尚未在初始化时启动的组件)。
ContextStoppedEvent
在ConfigurableApplicationContext接口上使用stop()方法停止ApplicationContext, 并且ApplicationContext停止后发布时间此处,“已停止”表示所有生命周期的bean均收到明确的停止信号。停止的上下文可以通过start()调用重新启动。
ContextClosedEvent
在ConfigurableApplicationContext接口上使用close()方法, 此时bean被销毁并且无法刷新或重新启动
RequestHandledEvent
仅用于Web事件, 请求完成后
ServletRequestHandledEvent
每次请求处理结束后,容器上下文都发布了一个ServletRequestHandledEvent事件
自定义事件
实现自定义事件的步骤
编写继承ApplicationEvent的事件类
编写实现ApplicationEventPublisherAware接口和接口中的setApplicationEventPublisher(ApplicationEventPublisher publisher)方法, 通过调用publisher的publishEvent()方法发布事件
编写实现ApplicationListener接口的监听类
实现自定义时间的代码示例
编写事件类
public class CustomEvent extends ApplicationEvent {
private String msg;
public CustomEvent(Object source) {
super(source);
}
public CustomEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
实现事件发布
@Component
public class CustomEventPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = publisher;
}
/**
* 发布消息
*/
public void publishMsg() {
this.publisher.publishEvent(new CustomEvent(this, "这是一个消息!"));
}}
实现事件监听
事件监听分为两种方式: 实现ApplicationListener接口, 使用@EventListener注解
实现ApplicationListener接口
当有多个事件的时候, 监听器会跟据ApplicationListener接口的范型判断时间类型
@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {
@Override
public void onApplicationEvent(CustomEvent customEvent) {
System.out.println("监听到事件消息:" + customEvent.getMsg());
}
}
使用@EventListener注解
当有多个时间的时候, 监听器根据方法的参数判断事件类型
@Component
public class CustomEventListener {
@EventListener
public void receiveEvent(CustomEvent customEvent) {
System.out.println("监听到事件消息:" + customEvent.getMsg());
}
}
自定义代码测试结果
测试代码
@SpringBootTest
class EventApplicationTests {
@Autowired
private CustomEventPublisher publisher;
@Test
void contextLoads() {
publisher.publishMsg();
}
}
————————————————
版权声明:本文为CSDN博主「码代马」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37296487/article/details/109563799
————————————————
版权声明:本文为CSDN博主「bat在等我」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_46836425/article/details/125041306
spring与springboot
spring需要使用组件扫描才能使用@controller等,springBoot只要和主启动类同包或者子包下就不用加
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?