Spring设计模式剖析之观察者模式

  • 观察者模式
  • 定义:
  • 优点:
  • 缺点:
  • 正文
  • Spring观察者模式
  • ApplicationContext事件监听
  • 1.创建ApplicationEventListener 监听对象
  • 2.将ApplicationEventListener 对象添加到容器中spring-event.xml
  • 3测试
  • 自定义监听事件
  • 1.定义事件监听对象: MessageEventListener
  • 2.定义事件对象: MessageEvent
  • 3.将对象添加到容器中:MessageEventListener
  • 4.创建测试
  • 5.结果


观察者模式

定义:

对象之间存在一对多或者一对一依赖,当一个对象改变状态,依赖它的对象会收到通知并自动更新。 MQ其实就属于一种观察者模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

优点:

1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。

缺点:

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

正文

Spring观察者模式

ApplicationContext事件机制是观察者设计模式实现的通过ApplicationEvent类与借口ApplicationListener 借口实现的
可以实现ApplicationContext事件的处理
容器中如果有个ApplicationListener Bean,当ApplicationContext发布applicationEvent时,ApplicationListener Bean 会自动触发,这种事件机制都必须需要程序显示的触发。
其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听 ContextRefreshedEvent 事件,
当所有的bean都初始化完成并被成功装载后会触发该事件,实现
ApplicationListener 接口可以收到监听动作,然后可以写自己的逻辑。
同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。
对象说明:

1、ApplicationContext容器对象
2、ApplicationEvent事件对象(ContextRefreshedEvent容器刷新事件)
3、ApplicationListener事件监听对象

ApplicationContext事件监听

当ApplicationContext内的Bean对象初始化完成时,此时可以通过监听 ContextRefreshedEvent 得到通知!
案例:

1.创建ApplicationEventListener 监听对象
package com.tukecloud.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/*****
 * @Author: jamison huang
 * @Description: 创建监听对象
 ****/
public class ApplicationEventListener implements ApplicationListener<ContextRefreshedEvent> {

    //发生指定事件后会触发该方法执行
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
        System.out.println("监听到容器初始化完成!");
    }
}
2.将ApplicationEventListener 对象添加到容器中spring-event.xml
<?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 id="applicationEventListener" class="com.tukecloud.spring.ApplicationEventListener"/>
</beans>
3测试
public class SpringContextTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-event.xml");
    }
}

结果:

监听到容器初始化完成!

自定义监听事件

1.定义事件监听对象: MessageEventListener
public class MessageEventListener implements ApplicationListener {

    //监听触发执行
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("监听到了对应事件!"+applicationEvent.getClass().getName());
    }
}
2.定义事件对象: MessageEvent
public class MessageEvent extends ApplicationEvent {

    /***
     * 可以用于传递数据
     */
    public MessageEvent(Object source) {
        super(source);
    }
}
3.将对象添加到容器中:MessageEventListener
<bean id="messageEventListener" class="com.tukecloud.spring.MessageEventListener"/>
4.创建测试
public static void main(String[] args) {
        ApplicationContext applicationConext = new ClassPathXmlApplicationContext("spring-event.xml");
        //添加一个自定义事件
        applicationConext.publishEvent(new MessageEvent("hi!"));
    }
5.结果

监听到了对应事件!org.springframework.context.event.ContextRefreshedEvent
监听到了对应事件!com.tukecloud.spring.MessageEvent