目录应用场景举例观察者模式的优点观察者模式的缺点Spring中的观察者模式代码实现1、定义事件类型2、监听者 - 短信3、监听者 - 邮件4、发布者 - 发布事件5、测试发布-监听应用场景举例· 一个事件多个处理方式的场景。·当用户下单成功后会发送手机短信、邮箱、微信、等。观察者模式的优点观察者和被观察者之间是抽象耦合不管是增加观察者还是被观察者都非常容易扩展。建立一套触发机制。观察者模式的缺点观察者模式需要考虑开发效率和运行效率问题一个被观察者多个观察者开发和调试比较复杂Java消息的通知默认是顺序执行的一个观察者卡壳会影响整体的执行效率。这种情况一般考虑异步的方式。Spring中的观察者模式ApplicationContext中事件处理是由ApplicationEvent类和ApplicationListener接口来提供的。如果一个Bean实现了ApplicationListener接口并且已经发布到容器中去每次ApplicationContext发布一个ApplicationEvent事件这个Bean就会接到通知。Spring事件机制是观察者模式的实现。Spring中的事件机制涉及到者几个类文件 ApplicationListener监听者事件监听接口ApplicationEventPublisherAware发布者事件发布类接口ApplicationEvent事件类型定义事件的数据结构类代码实现1、定义事件类型就是定义事件的数据结构。/** * 定义事件类型定义事件的数据结构 */ 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; } }2、监听者 - 短信/** * 监听者 - 短信监听异步执行 */ Component public class SmsListener implements ApplicationListenerUserRegisterEvent { Override Async //异步 public void onApplicationEvent(UserRegisterEvent event) { System.out.println(Thread.currentThread() ,短信监听到 event.getUsername() , event.getSource()); } }3、监听者 - 邮件Component public class EmailListener implements ApplicationListenerOrderEvent { private static final Logger logger Logger.getLogger(EmailListener.class); Override Async public void onApplicationEvent(OrderEvent event) { System.out.println(Thread.currentThread() ,邮件监听到 event.getMessage() , event.getSource()); } }4、发布者 - 发布事件/** * 发布者 */ Service public class UserServicePublisher implements ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher; Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher applicationEventPublisher; } /** * 发布 */ public void register(String username) { System.out.println(发布 username); applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username)); } }最后在启动类上加上开启异步注解 EnableAsync否则监听者将会串行执行。5、测试发布-监听RestController public class TestController { Autowired private UserServicePublisher userService; RequestMapping(/test/register) public void testRegister(){ userService.register(王明); } }请求http://127.0.0.1:8080/test/register然后查看控制台打印