Spring事件监听(转)

转载:https://www.cnblogs.com/better-farther-world2099/articles/15798032.html

一、前言

事件监听机制也是设计模式中观察者模式的一种实现。在spring中主要有实现ApplicationListener 接口和@EventListener 注解两种方式实现。

实现事件监听机制需要以下三个角色:

1、事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。
2、监听器(listener)具体根据事件发生的业务处理模块,这里可以接收处理事件中封装的对象或字符串。
3、事件发布者(publisher)事件发生的触发者。

二、ApplicationListener 接口

ApplicationListener 接口的定义如下:

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

  它是一个泛型接口,泛型的类型必须是 ApplicationEvent 及其子类,只要实现了这个接口,那么当容器有相应的事件触发时,就能触发 onApplicationEvent 方法。ApplicationEvent 类的子类有很多,Spring 框架自带的如下几个。

使用方法很简单,就是实现一个 ApplicationListener 接口,并且将加入到容器中就行。

复制代码
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationStartedEvent> {

//    @Override
//    public void onApplicationEvent(ApplicationEvent event) {
//        System.out.println("事件触发:"+event.getClass().getName());
//    }
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("事件触发:"+event.getClass().getName());
    }

}
复制代码

可以看到控制台输出:这样就触发了spring默认的一些事件。

事件触发:org.springframework.boot.context.event.ApplicationStartedEvent
事件触发:org.springframework.boot.context.event.ApplicationReadyEvent

自定义事件监听

定义事件
首先,我们需要定义一个时间(MyTestEvent),需要继承Spring的ApplicationEvent

复制代码
public class MyTestEvent extends ApplicationEvent {

    private static final long serialVersionUID = 1L;

    private String msg ;

    public MyTestEvent(Object source,String msg) {
        super(source);
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
复制代码

定义监听器
需要定义一下监听器,自己定义的监听器需要实现ApplicationListener,同时泛型参数要加上自己要监听的事件Class名,在重写的方法onApplicationEvent中,添加自己的业务处理:

复制代码
@Component
public class MyNoAnnotationListener implements ApplicationListener<MyTestEvent> {

    @Override
    public void onApplicationEvent(MyTestEvent event) {
        System.out.println("非注解监听器:" + event.getMsg());
    }

}
复制代码

事件发布
有了事件,有了事件监听者,那么什么时候触发这个事件呢?每次想让监听器收到事件通知的时候,就可以调用一下事件发布的操作。首先在类里自动注入了ApplicationEventPublisher,这个也就是我们的ApplicationContext,它实现了这个接口。

复制代码
@RestController
@RequestMapping("testEventController")
public class MyTestEventController {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @RequestMapping(value = "/testPublishEvent1" )
    public void testPublishEvent(){
        applicationEventPublisher.publishEvent(new MyTestEvent(this, "我来了"));
    }

}
复制代码

输出结果如下图所示:

非注解监听器:我来了

三、@EventListener 注解

复制代码
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
    @AliasFor("classes")
    Class<?>[] value() default {};  //监听的类
 
    @AliasFor("value")
    Class<?>[] classes() default {};
 
    String condition() default "";
}
复制代码

简单使用
除了通过实现接口,还可以使用@EventListener 注解,实现对任意的方法都能监听事件。
在任意方法上标注@EventListener 注解,指定 classes,即需要处理的事件类型,一般就是 ApplicationEven 及其子类,可以设置多项。

复制代码
@Compoment
public class CustomListener {

    @EventListener(classes = {SpringApplicationEvent.class})
    public void listen(SpringApplicationEvent event) {
        System.out.println("注解事件触发:" + event.getClass().getName());
    }

}
复制代码

启动项目

可以看到控制台和之前的输出是一样的:

注解事件触发:org.springframework.boot.context.event.ApplicationStartedEvent
注解事件触发:org.springframework.boot.context.event.ApplicationReadyEvent

使用注解的好处是不用每次都去实现ApplicationListener,可以在一个class中定义多个方法,用@EventListener来做方法级别的注解。
和上面类似,事件以及事件发布不需要改变,只要这样定义监听器即可。

此时,就可以有一个发布,两个监听器监听到发布的消息了,一个是注解方式,一个是非注解方式
结果:

 

spring观察者模式demo

复制代码
// Event事件
public class DemoEvent extends ApplicationEvent {
  private String message;

  public DemoEvent(Object source, String message) {
    super(source);
  }

  public String getMessage() {
    return this.message;
  }
}

// Listener监听者
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {
  @Override
  public void onApplicationEvent(DemoEvent demoEvent) {
    String message = demoEvent.getMessage();
    System.out.println(message);
  }
}

// Publisher发送者
@Component
public class DemoPublisher {
  @Autowired
  private ApplicationContext applicationContext;

  public void publishEvent(DemoEvent demoEvent) {
    this.applicationContext.publishEvent(demoEvent);
  }
}
复制代码
posted @   Mars.wang  阅读(530)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示