Spring中的观察者模式运用

**

观察者模式

对象之间一对一或者一对多依赖,当一个对象改变状态的时候,依赖他的对象会受到通知并且自动各更新,MQ其实就是属于观察者模式,发布者发布消息,订阅者获取消息,订阅就可以获取消息没订阅就获取不到信息;
**

观察者模式的优点

观察者和被观察者是抽象耦合的,建立了一套触发机制

观察者模式的缺点

如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。(比如A 和B 之前相互观察 就进入了死循环 )

**

spring 标题中的观察者模式

ApplicationContext 事件机制是观察者设计模式的实现,通过 ApplicationEvent 类和ApplicationListener 接口可以实现 ApplicationContext 事件处理;
ApplicationListener 属于观察者对象,一旦ApplicationContext容器中的内容 发生变化就会触发ApplicationEvent事件 ,ApplicationListener 可以监听到事件。

验证Sprig中的观察者模式:

在spring中的ApplicationContext容器在初始化的时候就会出触发ApplicationEvent事件并且

ApplicationListener

可以监听到,那么就可以验证如下:

通过解析spring-event.xml文件创建ApplicationContex容器并且完成初始化验证

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置文件中配置-->
    <bean class="com.itheima.spring.ApplicationContextListener"></bean>

</beans>
public class SpringApplicationTest {

    /*****
     * 1.创建ApplicationContext
     * 2.执行相关事件 ApplicationEvent:容器初始化完成
     * 3.监听事件执行信息A pplicationListener
     */
    public static void main(String[] args) {
        //1.创建ApplicationContext容器,加载和初始化容器,加载完毕就相当于执行了事件
        //创建容器-->初始化bean完成---->事件ApplicationEvent--->监听ApplicationListener
        ApplicationContext act = new ClassPathXmlApplicationContext("spring-event.xml");
    }

自定义一个事件MessageEvent并且实现ApplicationEvent接口

public class MessageEvent extends ApplicationEvent {

    /***
     * 可以用于传递数据
     */
    public MessageEvent(Object source) {
        super(source);
    }
}

有了事件之后还需要自定义一个监听用来接收监听到事件,自定义ApplicationContextListener监听 需要交给Spring容器管理, 实现ApplicationListener接口并且重写onApplicationEvent方法, ApplicationListener监听的是ContextRefreshedEvent事件所以实现的接口上要添加泛型,如果不指定ContextRefreshedEvent监听的是所有的事件

public class ApplicationContextListener implements ApplicationListener<ContextRefreshedEvent> {

    //监听  ContextRefreshedEvent:容器完成初始化加载事件
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
       //获取Bean初始化完成之后的ApplicationContext
        System.out.println("事件执行完成之后监听方法");
        ApplicationContext act = event.getApplicationContext();
        //初始化数据数据操作
        System.out.println("容器初始化完成!!");
    }

运行程序之后发现,ApplicationContext在初始话完成后ApplicationListener成功监听
在这里插入图片描述

Spring的观察者模式源码分析

进入当前ApplicationCotext容器实列中,容器中有一个ApplicationListener,并且是一个Set集合
在这里插入图片描述
当每个容器出发ApplicationEvent事件的时候,此时ApplicationListener会自动触发;debug进入ApplicationCotext实列

在这里插入图片描述
容器通过publishEvent方法中有一个multicastEvent方法,参数是ApplicationListener,debug进入该方法进入multicastEvent方法,里面有一个invokeListener方法并且进入该方法,
在这里插入图片描述进入invokeListener方法后 ,源码中有又执行了doInvokeListener方法中的onApplicationEvent方法

总结

:ApplicationContextr容器中有一个Set 接口集合,集合中存放着ApplicationListener,ApplicationConext对象中一旦内容发发生变化会操作ApplicationEvent,并且循环调用Set集合中ApplicationLisener中的onApplicationEvent方法;这也就是自定义接口中需要实现的方法,整个监听事件的源码运用的就是观察者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值