**
观察者模式
对象之间一对一或者一对多依赖,当一个对象改变状态的时候,依赖他的对象会受到通知并且自动各更新,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方法;这也就是自定义接口中需要实现的方法,整个监听事件的源码运用的就是观察者模式