观察者模式

介绍

定义: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
其实说白了,就是当一个对象状态发生变化,通过方法回调通知其他对象,其他对象通过回调信息作出相应处理
为什么整理这个设计模式,是因为受spring监听器感发,在一个自己的小应用中使用了该模式所以整理一下。

代码理解

public class Test {
    public static void main(String[] args{
        Publish publish = new Publish();
        //添加观察者
        publish.addSubscribes(new ConcreteSubscribe());
        System.out.println("触发观察者");
        publish.onMessage("方法调用了");
    }
}

/**
 * 抽象观察者
 */

interface Subscribe {
    void onMessage(String msg);
}

/**
 * 具体观察者
 */

class ConcreteSubscribe implements Subscribe {

    /**
     * 观察(回调)方法
     *
     * @param msg 消息
     */

    @Override
    public void onMessage(String msg
{
        System.out.println("收到消息: " + msg);
    }
}

/**
 * 被观察者
 */

class Publish {
    private List<Subscribe> subscribes = new ArrayList<>();

    public void addSubscribes (Subscribe subscribe{
        subscribes.add(subscribe);
    }

    /**
     * 被观察的方法
     *
     * @param msg 消息
     */

    public void onMessage(String msg{
        for (Subscribe subscribe : subscribes) {
            subscribe.onMessage(msg);
        }
    }
}

看完代码,应该会对观察者模式了解了七七八八了,感觉上还是比较简单的

实际运用

不久前自己闲来写的一个关于quartz定时任务的组件中使用观察者模式,主要作用是用来监听定时任务异常问题,当任务运行出现异常,可以让使用者根据自身情况作出相应的处理。

点此查看组件源码

主流程讲解:

  1. 创建监听接口(观察者)并配合注解public @interface QuartzListener {}
    注解的作用是使实现监听接口的类的可以被spring扫描到并加入容器,以便于被观察者添加监听类
/**
 * 定时任务监听类
 *
 * @author guochunyun(guochunyun @ nvoccservicecenter.com)
 * @date 2020/1/15 11:36 上午
 */

public interface QuartzListener {

    /**
     * 定时任务监听回调方法
     *
     * @param quartzEvent 信息类
     */

    void onListener(QuartzEvent quartzEvent);
}
  1. 创建发布类(被观察者)并从容器中获取到需要通知的类
/**
 * @author guochunyun(guochunyun @ nvoccservicecenter.com)
 * @date 2020/1/15 11:42 上午
 */

public class QuartzListenerPush implements ApplicationContextAware {
    private List<QuartzListener> quartzListeners = new ArrayList<>();

    /**
     * 添加监听器
     *
     * @param context spring上下文
     * @throws BeansException
     */

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        Map<String, Object> map = context.getBeansWithAnnotation(com.xiaoguo.annotation.QuartzListener.class);
        for (Map.Entry<String, Object> o : map.entrySet()) {
            Object obj = o.getValue();
            if (obj instanceof QuartzListener) {
                quartzListeners.add((QuartzListener) obj);
            }
        }
    }

    /**
     * 监听信息推送
     *
     * @param quartzEvent 监听信息
     */

    public void push(QuartzEvent quartzEvent) {
        for (QuartzListener quartzListener : quartzListeners) {
            quartzListener.onListener(quartzEvent);
        }
    }
}
  1. 监听到异常信息通知给监听类
/**
     * 定时任务异常拦截
     *
     * @param joinPoint
     * @param throwable
     * @throws Exception
     */

    @AfterThrowing(value = "point()", throwing = "throwable")
    public void error(JoinPoint joinPoint, Throwable throwable) throws Exception {
        //获取当前定时任务信息
        JobInfo jobInfo = getJobInfo(joinPoint.getArgs());
        //监听异常信息
//        context.publishEvent(new QuartzEvent<Throwable>(jobInfo).setErrorContent(throwable));
        quartzListenerPush.push(new QuartzEvent<Throwable>(jobInfo).setErrorContent(throwable));
        //更新定时任务信息
        if (jobInfo != null) {
            updateJobInfo(jobInfo.getJobClass().getName(), nullfalse);
        }
    }
  1. 具体监听类收到信息作出处理
@com.xiaoguo.annotation.QuartzListener
public class JobListenerNew implements QuartzListener {

    @Override
    public void onListener(QuartzEvent quartzEvent) {
        System.out.println("监听到信息: " + quartzEvent);
    }
}
原文地址:https://www.cnblogs.com/chunyun/p/12209436.html