介绍
定义: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
其实说白了,就是当一个对象状态发生变化,通过方法回调通知其他对象,其他对象通过回调信息作出相应处理
为什么整理这个设计模式,是因为受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定时任务的组件中使用观察者模式,主要作用是用来监听定时任务异常问题,当任务运行出现异常,可以让使用者根据自身情况作出相应的处理。
主流程讲解:
- 创建监听接口(观察者)并配合注解public @interface QuartzListener {}
注解的作用是使实现监听接口的类的可以被spring扫描到并加入容器,以便于被观察者添加监听类
/**
* 定时任务监听类
*
* @author guochunyun(guochunyun @ nvoccservicecenter.com)
* @date 2020/1/15 11:36 上午
*/
public interface QuartzListener {
/**
* 定时任务监听回调方法
*
* @param quartzEvent 信息类
*/
void onListener(QuartzEvent quartzEvent);
}
- 创建发布类(被观察者)并从容器中获取到需要通知的类
/**
* @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);
}
}
}
- 监听到异常信息通知给监听类
/**
* 定时任务异常拦截
*
* @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(), null, false);
}
}
- 具体监听类收到信息作出处理
@com.xiaoguo.annotation.QuartzListener
public class JobListenerNew implements QuartzListener {
@Override
public void onListener(QuartzEvent quartzEvent) {
System.out.println("监听到信息: " + quartzEvent);
}
}