深入理解:Spring监听器底层原理与使用方法

一·监听器的底层原理:

(1)底层利用观察者模式实现,项目任何位置提前注册监听器(观察者)到主题map集合里面(key为事件类型,value为对应的监听器对象集合List);项目任何位置一旦利用主题发布事件操作时,就会批量触发对应的监听器响应方法。

(2)主题发布事件方法本质就是,从主题map里面获取出对应的监听器集合,然后循环调用监听器的固定响应方法就行了,至于是同步还是异步,就看调用监听器固定方法时是否利用多线程操作了。

二·监听器机制作用:

1.解耦业务逻辑

2.实现异步处理

3.方便系统集成和扩展性

三·关于监听器的一些个人见解:

(1)监听器在程序开发中,实际上是一种开发风格或者设计模式,用不用其实都能实现需求结果。

例如:MVC三层架构开发,如果我一定要把所有代码写在控制层,这也是可以实现功能需求的,只是不太利于后面扩展延伸与二次开发罢了。

(2)利用监听器可以在各种地方获取事件源对象的所有信息

因为事件对象内部包括源对象,发布操作时又会将事件对象传给监听器,所以监听器内部能够获取所有信息,至于后续是同步操作还是异步操作,就看有没有使用多线程了。如果监听器也能够任意获取或者注册的话,那就可以实现在项目任意地方实现监控某个事件的自动化操作

四·模拟实现一个原生的监听器案例:利用监听器设计模式

第一步:创建一个事件类:MyEvent

事件类主要起一个作用:那就是通过事件对象可以获取事件源对象,监听器可以用上!
在这里插入图片描述

/**
 * @Description 自定义事件
 * @Author LiuMingFu
 * @Date 2024/8/30 00:57
 */
public class MyEvent {

    /**
     * 事件对象构造方法
     *
     * @param source 源对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    public MyEvent(Object source) {
        System.out.println("进入事件对象,收到源对象:" + source);
    }
}

第二步:创建一个自定义监听器,MyPersonListener类

其实本质就是一个普通类里面声明一个普通方法!监听器里面也可以根据事件对象获取事件源对象,然后进行一系列处理。
在这里插入图片描述

/**
 * @Description 自定义监听器
 * @Author LiuMingFu
 * @Date 2024/8/30 00:58
 */
public class MyListener {


    /**
     * 事件监听响应方法
     *
     * @param event 事件对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    public void onApplicationEvent(MyEvent event) {
        System.out.println("进入监听器,收到事件对象:" + event);
    }
}

第三步:创建自定义主题类,用于注册监听器,发布自定义事件操作

不能使用get/set方法、构造方法赋值,需要专门声明一个方法进行赋值,这就是注册监听器方法!
在这里插入图片描述

/**
 * @Description 演示在项目任何地方发布事件
 * @Author LiuMingFu
 * @Date 2024/8/30 00:59
 */
public class Subject {

    //监听器集合
    private static Map<Object, List<MyListener>> listeners = new HashMap<>();


    /**
     * 注册监听器对象,且指定监视哪个事件对象
     *
     * @param event    事件对象
     * @param listener 监听器对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    public static void registerListener(MyEvent event, MyListener listener) {
        if (listeners.get(event) != null) {
            //存在则继续往集合里面添加
            listeners.get(event).add(listener);
        } else {
            //不存在则创建集合,并添加
            listeners.put(event, new ArrayList<>(Arrays.asList(listener)));
        }
    }

    /**
     * 发布自定义事件
     *
     * @param event 自定义事件对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    public static void publishEvent(MyEvent event) {
        System.out.println("进入主题,开始发布自定义事件");
        List<MyListener> myListeners = listeners.get(event);
        for (MyListener myListener : myListeners) {
            myListener.onApplicationEvent(event);
        }
    }
}

第四步:开始测试

一旦调用depart方法,就会先去调用监听器的print方法;这样就相当于把Person类的depart方法监控起来了,也就相当于将事件源的信息告诉了另一个类监听器!!!
在这里插入图片描述

public class Main {
    public static void main(String[] args) {
        //创建一个自定义监听器
        MyListener listener = new MyListener();
        //创建第二个自定义监听器
        MyListener listener2 = new MyListener();
        //创建一个自定义事件
        MyEvent myEvent = new MyEvent("自定义模拟事件对象");
        //注册监听器到主题里面:这样就可以实现在项目任何地方注册监听器
        Subject.registerListener(myEvent, listener);
        Subject.registerListener(myEvent, listener2);
        //使用主题发布自定义事件,这样可以实现在项目任何地方发布自定义事件
        Subject.publishEvent(myEvent);
    }
}

五·Spring框架监听器的使用步骤

1.自定义Spring框架事件:需要继承ApplicationEvent类

注意:不交给spring管理,因为Spring默认创建单例bean放入IOC容器里面,但是该事件对象是随用随创建的,并不是单例的对象
在这里插入图片描述

/**
 * @Description 自定义Spring框架事件
 * @Author LiuMingFu
 * @Date 2024/8/30 00:57
 */
public class MyEvent extends ApplicationEvent {

    /**
     * 事件对象构造方法
     *
     * @param source 源对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    public MyEvent(Object source) {
        super(source);
        System.out.println("进入事件对象,收到源对象:" + source);
    }
}

2.自定义Spring框架监听器

方式一:需要实现ApplicationListener<T>接口

监听器注入IOC就相当于将自定义监听器注册进容器里面了,后续才能被Spring框架利用观察者模式,进行自动监听触发操作
在这里插入图片描述

/**
 * @Description 自定义Spring框架监听器
 * @Author LiuMingFu
 * @Date 2024/8/30 01:12
 */
@Component //注入到spring容器中,相当于注册监听器
public class MyListener2 implements ApplicationListener<MyEvent> {


    /**
     * Handle an application event.
     *
     * @param event the event to respond to
     */
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("进入监听器2,收到事件对象:" + event.getSource());
    }
}

方式二:使用@EventListener注解

在这里插入图片描述

/**
 * @Description 自定义Spring框架监听器
 * @Author LiuMingFu
 * @Date 2024/8/30 00:58
 */
@Component
public class MyListener {


    /**
     * 事件监听方法
     *
     * @param event 事件对象
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    @EventListener(value = {MyEvent.class})
    public void onApplicationEvent(MyEvent event) {
        System.out.println("进入监听器,收到事件对象:" + event.getSource());
    }
}

3.发布事件操作:

方式一:使用Spring框架自带的ApplicationEventPublisher接口发布

在这里插入图片描述

/**
 * @Description 演示在项目任何地方发布事件
 * @Author LiuMingFu
 * @Date 2024/8/30 00:59
 */
@RestController
public class PublisherController {

    //注入Spring的事件发布器对象,框架自带
    @Resource
    private ApplicationEventPublisher eventPublisher;


    /**
     * 发布自定义事件
     *
     * @return
     * @author LiuMingFu
     * @date 2024/8/30
     */
    @RequestMapping("/publish")
    public void publishEvent() {
        System.out.println("进入控制器,开始发布自定义事件");
        //发布事件
        eventPublisher.publishEvent(new MyEvent("hello lmf"));
    }
}

方式二:使用IOC容器发布

在这里插入图片描述

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);

        //利用IOC容器,发布事件
        context.publishEvent(new MyEvent("ioc发布自定义事件"));
        
    }
}

4.演示执行结果:

在这里插入图片描述

在这里插入图片描述

六·参考文献:

1.监听器入门看这篇就够了
https://segmentfault.com/a/1190000013240470

2.SpringBoot中@EventListener注解的使用
https://blog.csdn.net/weixin_48033662/article/details/126337805

3.这次终于把Spring的监听器讲明白了
https://javayz.blog.csdn.net/article/details/121623148

4.深入理解Spring的容器内事件发布监听机制
https://www.cnblogs.com/takumicx/p/9972461.html

5.spring中的监听器的使用(注解和非注解方式)
https://blog.csdn.net/erbao_2014/article/details/68924231

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ideal-cs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值