领域事件
观察者模式
大家在日常业务开发工作中相信多多少少遇到过下面这样的几个场景:
- 当某一个特定事件或动作发生以后,需要执行很多联动动作,如果串行去执行的话太耗时,如果引入消息中间件的话又太重了;
- 想要针对不同的传参执行不同的策略,也就是我们常说的策略模式,但
10 个人可能有10 种不同的写法,夹杂在一起总感觉不那么优雅; - 自己的系统想要调用其他系统提供的能力,但其他系统总是偶尔给你一点“小惊喜”,可能因网络问题报超时异常或被调用的某一台分布式应用机器突然宕机,我们想要优雅无侵入式地引入重试机制。
其实上面提到的几个典型业务开发场景

使用观察者模式后:

- **ApplicationEvent:
** 通过继承它,实现自定义事件。另外,通过它的source 属性可以获取事件源,timestamp 属性可以获得发生时间。 - **ApplicationEventPublisher:
** 通过实现它,来发布变更事件。 - **ApplicationEventListener:
** 通过实现它,来监听指定类型事件并响应动作。这里就以上面的用户注册为例,来看看代码示例。首先定义用户注册事件UserRegisterEvent 。
public class UserRegisterEvent extends ApplicationEvent {
/**
* 用户名
*/
private String username;
public UserRegisterEvent(Object source) {
super(source);
}
public UserRegisterEvent(Object source, String username) {
super(source);
this.username = username;
}
public String getUsername() {
return username;
}
}
然后定义用户注册服务类,实现
@Service
public class UserService implements ApplicationEventPublisherAware { // <1>
private Logger logger = LoggerFactory.getLogger(getClass());
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void register(String username) {
// ... 执行注册逻辑
logger.info("[register][执行用户({}) 的注册逻辑]", username);
// <2> ... 发布
applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));
}
}
创建邮箱
@Service
public class EmailService implements ApplicationListener<UserRegisterEvent> { // <1>
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
@Async// <3>
public void onApplicationEvent(UserRegisterEvent event) { // <2>
logger.info("[onApplicationEvent][给用户({}) 发送邮件]", event.getUsername());
}
}
创建优惠券
@Service
publicclass CouponService {
private Logger logger = LoggerFactory.getLogger(getClass());
@EventListener// <1>
public void addCoupon(UserRegisterEvent event) {
logger.info("[addCoupon][给用户({}) 发放优惠劵]", event.getUsername());
}
}
简单来说,发布订阅模式属于广义上的观察者模式,在观察者模式的
