spring 中观察者模式经典应用

1.spring 是一个强大的应用结构,有很多优点,设计模式也是应用的淋淋尽致,一下简单介绍spring 中观察者应用。

首先我们通过源码可以清晰的知道,在我们spring beandefinition等初始化之后,有一个监听器注册的方法

// Check for listener beans and register them.
registerListeners();

这是注册的一个入口,

spring 中观察者模式经典应用

看上述代码,大致描述下,首先获取实现spplicationlistener接口的所有类,将其注册到容器中,然后创建发布监听,

spring 中观察者模式经典应用

可以看到,这里做的工作就是启动任务线程,任务的最终调用是调用实现applicationlistener的

onApplicationEvent方法

spring 中观察者模式经典应用

整个过程就是这样,那么让我们简单实现模拟一个这样的过程

1.编写一个监听器

package com.consult.listen;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class MyListen implements ApplicationListener {

    public void onApplicationEvent(ApplicationEvent arg0) {
        
        if(arg0 instanceof MyEvent) {
            MyEvent event = (MyEvent)arg0;
            
            System.out.println(this.getClass().getName() + event.getParam1());
            System.out.println(this.getClass().getName() + event.getParam2());
            System.out.println(this.getClass().getName() + event.getSource());
            
        }
    }
    
}

2.监听事件

package com.consult.listen;

import org.springframework.context.ApplicationEvent;

public class MyEvent extends ApplicationEvent {
    
    public String param1;
    
    public String param2;
    
    public MyEvent(Object source,String param1,String param2) {
        super(source);
        this.param1 = param1;
        this.param2 = param2;
    }

    public Object getSource() {
        return super.getSource();
    }

    public String getParam1() {
        return param1;
    }

    public void setParam1(String param1) {
        this.param1 = param1;
    }

    public String getParam2() {
        return param2;
    }

    public void setParam2(String param2) {
        this.param2 = param2;
    }
    
}
注意一定定义一个构造函数,测试类如下:

package com.consult.listen;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.consult.postprocess.Student;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class MyTest implements ApplicationContextAware {
    
    public ApplicationContext context;
    
    @Test
    public void test1(){
        
        Student s = (Student)context.getBean("jackstudent");
        
        System.out.println(s.getUsername());
        System.out.println(s.getPassword());
        System.out.println(s.getSchool());
    }

    @Override
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        this.context = arg0;
        
    }
    
    @Test
    public void test2() {
        MyEvent event = new MyEvent("source","param1","param2");
        context.publishEvent(event);
    }
    
    

}

以上测试类配置没有写,搞这个的很简单,大致代码如上述。
好了,整个的源码解析和简单应用就是这样。下面是模式的基础概念:

一. 观察者模式简介
1. 定义
观察者模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。

2. 意义
此设计模式最重要的作用就是 解耦!将观察者与被观察者解耦,使得他们之间的依赖性更小。spring 中观察者模式经典应用


Subject:就是“被观察”的角色,它将所有观察者对象的引用保存在一个集合中。
Observer:是抽象的“观察”角色,它定义了一个更新接口,使得在被观察者状态发生改变时通知自己。
ConcreteObserver:具体的观察者。
二. 观察者模式实现
以上理论相信大家并不模式,现在我们来应用到实际中。

1. 被观察者Subject对象
首先是一个Subject类的父类,它实现了维护装有观察者引用集合的功能。

public class Subject {
    //保存注册的观察者对象
    private List<Observer> mObervers = new ArrayList<>();

    //注册观察者对象
    public void attach(Observer observer) {
        mObervers.add(observer);
        Log.e("SZH", "attach an observer");
    }

    //注销观察者对象
    public void detach(Observer observer) {
        mObervers.remove(observer);
        Log.e("SZH", "detach an observer");
    }

    //通知所有注册的观察者对象
    public void notifyEveryOne(String newState) {
        for (Observer observer : mObervers) {
            observer.update(newState);
        }
    }
}

接着是一个具体的被观察者对象

public class ConcreteSubject extends Subject {
    private String state;

    public String getState() {
        return state;
    }

    public void change(String newState) {
        state = newState;
        Log.e("SZH", "concreteSubject state:" + newState);

        //状态发生改变,通知观察者
        notifyEveryOne(newState);
    }
}

2. 观察者Observer对象
首先是一个接口,抽象出了一个及时更新的方法

public interface Observer {
    void update(String newState);
}
1
2
3
接着是几个观察者对象。

public class ObserverA implements Observer {

    //观察者状态
    private String observerState;

    @Override
    public void update(String newState) {
        //更新观察者状态,让它与目标状态一致
        observerState = newState;
        Log.e("SZH", "接收到消息:" + newState + ";我是A模块,快来抢吧!!");
    }
}

public class ObserverB implements Observer {
    //观察者状态
    private String observerState;

    @Override
    public void update(String newState) {
        //更新观察者状态,让它与目标状态一致
        observerState = newState;
        Log.e("SZH", "接收到消息:" + newState + ";我是B模块,快来抢吧!!");
    }
}

public class ObserverC implements Observer {
    //观察者状态
    private String observerState;

    @Override
    public void update(String newState) {
        //更新观察者状态,让它与目标状态一致
        observerState = newState;
        Log.e("SZH", "接收到消息:" + newState + ";我是C模块,快来抢吧!!");
    }
}
spring 中观察者模式经典应用

上一篇:Kafka高性能揭秘:sequence IO、PageCache、SendFile的应用详解


下一篇:React 之 Redux 的使用