1、概述
在设计模式中,观察者模式是一个比较常用的设计模式。维基百科解释如下:
观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。
在我们日常业务开发中,观察者模式对我们很大的一个作用,在于实现业务的解耦、传参等。以用户注册的场景来举例子,假设在用户注册完成时,需要给该用户发送邮件、发送优惠劵等等操作,如下图所示:
- UserService 在完成自身的用户注册逻辑之后,仅仅只需要发布一个 UserRegisterEvent 事件,而无需关注其它拓展逻辑。
- 其它 Service 可以自己订阅UserRegisterEvent 事件,实现自定义的拓展逻辑。
注意:发布订阅模式属于广义上的观察者模式
在观察者模式中,观察者需要直接订阅目标事件;在目标发出内容改变的事件后,直接接收事件并作出响应
╭─────────────╮ Fire Event ╭──────────────╮
│ │─────────────>│ │
│ Subject │ │ Observer │
│ │<─────────────│ │
╰─────────────╯ Subscribe ╰──────────────╯
在发布订阅模式中,发布者和订阅者之间多了一个发布通道;一方面从发布者接收事件,另一方面向订阅者发布事件;订阅者需要从事件通道订阅事件,以此避免发布者和订阅者之间产生依赖关系
╭─────────────╮ ╭───────────────╮ Fire Event ╭──────────────╮
│ │ Publish Event │ │───────────────>│ │
│ Publisher │────────────────>│ Event Channel │ │ Subscriber │
│ │ │ │<───────────────│ │
╰─────────────╯ ╰───────────────╯ Subscribe ╰──────────────╯
简单来说,发布订阅模式属于广义上的观察者模式,在观察者模式的 Subject 和 Observer 的基础上,引入 Event Channel 这个中介,进一步解耦。
2、事件模式中的概念
**事件源:**事件的触发者,比如注册用户信息,入库,发布“用户XX注册成功”。
**事件:**描述发生了什么事情的对象,比如:XX注册成功的事件
**事件监听器:**监听到事件发生的时候,做一些处理,比如 注册成功后发送邮件、赠送积分、发优惠券…
3、spring事件使用步骤
-
定义事件
自定义事件,需要继承ApplicationEvent类,实现自定义事件。另外,通过它的
source
属性可以获取事件源,timestamp
属性可以获得发生时间。 -
定义监听器
自定义事件监听器,需要实现ApplicationListener接口,实现onApplicationEvent方法,处理感兴趣的事件
-
创建事件广播器
创建事件广播器实现ApplicationEventMulticaster接口,也可以使用spring定义好的SimpleApplicationEventMulticaster:
ApplicationEventMulticaster applicationEventMulticaster = new SimpleApplicationEventMulticaster();
-
向广播器中注册事件监听器
将事件监听器注册到广播器ApplicationEventMulticaster中,
applicationEventMulticaster.addApplicationListener(new SendEmailOnOrderCreaterListener());
-
通过广播器发布事件
广播事件,调用ApplicationEventMulticaster#multicastEvent方法广播事件,此时广播器中对这个事件感兴趣的监听器会处理这个事件。
applicationEventMulticaster.multicastEvent(new OrderCreateEvent(applicationEventMulticaster, 1L));
4、使用方式
4.1 面向接口的方式
案例:实现用户注册成功后发布事件,然后在监听器中发送邮件的功能。
用户注册事件:
创建 UserRegisterEvent事件类,继承 ApplicationEvent 类,用户注册事件。代码如下:
public class UserRegistryEvent extends ApplicationEvent {
private String userName;
public UserRegistryEvent(Object source, String userName) {
super(source);
this.userName = userName;
}
public String getUserName() {
return userName;
}
}
发送邮件监听器:
创建 SendEmailListener 类,邮箱 Service。代码如下:
@Component
public class SendEmailListener impleme