本篇要点
-
介绍观察者模式和发布订阅模式的区别。
-
SpringBoot快速入门事件监听。
什么是观察者模式?
观察者模式是经典行为型设计模式之一。
在GoF的《设计模式》中,观察者模式的定义:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。如果你觉得比较抽象,接下来这个例子应该会让你有所感觉:
就拿用户注册功能为例吧,假设用户注册成功之后,我们将会发送邮件,优惠券等等操作,很容易就能写出下面的逻辑:
@RestController @RequestMapping("/user") public class SimpleUserController { @Autowired private SimpleEmailService emailService; @Autowired private SimpleCouponService couponService; @Autowired private SimpleUserService userService; @GetMapping("/register") public String register(String username) { // 注册 userService.register(username); // 发送邮件 emailService.sendEmail(username); // 发送优惠券 couponService.addCoupon(username); return "注册成功!"; } }
这样写会有什么问题呢?受王争老师启发:
-
方法调用时,同步阻塞导致响应变慢,需要异步非阻塞的解决方案。
-
注册接口此时做的事情:注册,发邮件,优惠券,违反单一职责的原则。当然,如果后续没有拓展和修改的需求,这样子倒可以接受。
-
如果后续注册的需求频繁变更,相应就需要频繁变更register方法,违反了开闭原则。
针对以上的问题,我们想一想解决的方案:
一、异步非阻塞的效果可以新开一个线程执行耗时的发送邮件任务,但频繁地创建和销毁线程比较耗时,并且并发线程数无法控制,创建过多的线程会导致堆栈溢出。
二、使用线程池执行任务解决上述问题。
@Service @Slf4j public class SimpleEmailService { // 启动一个线程执行耗时操作 public void sendEmail(String username) { Thread thread = new Thread(()->{ try { // 模拟发邮件耗时操作 Thread.s