小工具知识网

当前位置: 首页 > 行业知识 > 【spring】 ApplicationListener的使用及原理简析

行业知识

【spring】 ApplicationListener的使用及原理简析

2026-11-12 15:44:52 来源:互联网转载

文章目录

  • 使用示例:
  • 原理简析:

    前言:ApplicationListener 是spring提供的一个监听器,它可以实现一个简单的发布-订阅功能,用有点外行但最简单通俗的话来解释:监听到主业务在执行到了某个节点之后,在监听器里面做出相应的其它业务变更。下面我们具体看段代码,则能很快的理解:

    再次推荐博主原创idea插件: Equals Inspection , 如果经常使用Objects.equals方法,相信这个插件可以有所帮助

    (欢迎各位前往idea插件marketplace免费下载)

    使用示例:

    java代码:

    首先定义一个业务实体类,实体类定义字段、get set方法、构造函数

    import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructor/** * 模拟业务对象实体类 * @author csdn:孟秋与你 */public class MyBizEntity {    private String name;    private Integer age;}

    再定义一个事件,事件继承ApplicationEvent

    import org.springframework.context.ApplicationEvent;/** * 自定义事件(继承ApplicationEvent) * @author csdn:孟秋与你 */public class MyEvent extends ApplicationEvent {    public MyEvent(Object source) {        super(source);    }    public MyEvent() {        // java基础:如果父类只有有参构造 子类需要使用其它构造函数 必须在构造函数第一行调用super 因为子类也是调用父类的构造函数        super(null);        // do other    }}

    定义一个监听器,实现ApplicationListener接口:

    import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;import org.springframework.stereotype.Component;/** * 监听事件 */@Componentpublic class MyApplicationListener implements ApplicationListener {    @Override    public void onApplicationEvent(ApplicationEvent applicationEvent) {        // 必须判断自己要的类型  因为会监听到所有继承ApplicationEvent的事件        if (applicationEvent instanceof MyEvent) {            Object source = applicationEvent.getSource();            MyBizEntity bizEntity = (MyBizEntity) source;            System.out.println(bizEntity.getName() + ":------------name");        }    }}

    写一个接口进行测试, 此时监听器就能打印输出了

    import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping("/test/listener")@RestControllerpublic class MainBizController {    @Autowired    private ApplicationContext context;    @GetMapping    public String test() {        // do something                // 模拟要传递的业务对象        MyBizEntity bizEntity = new MyBizEntity("name",18);        MyEvent event = new MyEvent(bizEntity);        // 上下文 发布事件        context.publishEvent(event);        return "success";    }}

    原理简析:

    为什么发布了事件,监听器就能够监听到呢? 其实原理很简单,就是spring进行了一个朴实无华的直接调用, 我们来看看源码:

    context.publishEvent默认是调用AbstractApplicationContext类的publishEvent方法,而publishEvent方法里面调用了SimpleApplicationEventMulticaster 类的multicastEvent方法。

    tips: 为什么上下文有publishEvent方法 ?

    因为ApplicationContext继承了ApplicationEventPublisher

    SimpleApplicationEventMulticaster: 首先会获取所有实现了ApplicationListener的监听器 (get by type就可以获取到), 接着会执行 invokeListener方法

    我们看看最后doInvokeListener 做了什么:

    通过上面源码链路,我们不难发现 其实就是调用了publishEvent方法后,spring在我们不轻易能看到的地方 去调用了一下监听器的onApplicationEvent 方法而已,通过源码我们也可以看到 默认是同步调用(没有定义taskExecutor时), 本质上是一个解耦,把原本可能要写在一起的业务代码拆分了。

上一篇:西部数码备案流程全解析,轻松完成网站备案!

下一篇:香港VPS,极速网络体验与卓越服务的完美融合