1、背景
在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监听也是设计模式中:发布-订阅模式、观察者模式的一种实现。
观察者模式:简单的来讲就是你在做事情的时候身边有人在盯着你,当你做的某一件事情是旁边观察的人感兴趣的事情的时候,他会根据这个事情做一些其他的事,但是盯着你看的人必须要到你这里来登记,否则你无法通知到他(或者说他没有资格来盯着你做事情)。
对于 Spring 容器的一些事件,可以监听并且触发相应的方法。通常的方法有 2 种,ApplicationListener 接口和@EventListener 注解。
2、简介
要想顺利的创建监听器,并起作用,这个过程中需要这样几个角色:
- 1、事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。
- 2、监听器(listener)具体根据事件发生的业务处理模块,这里可以接收处理事件中封装的对象或字符串。
- 3、事件发布者(publisher)事件发生的触发者。
ApplicationListener 接口
ApplicationListener 接口的定义如下:
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
} 
它是一个泛型接口,泛型的类型必须是 ApplicationEvent 及其子类,只要实现了这个接口,那么当容器有相应的事件触发时,就能触发 onApplicationEvent 方法。ApplicationEvent 类的子类有很多,Spring 框架自带的如下几个。

3、简单使用
EventListener事件触发和监听器可以对代码解耦,在一些与业务无关的,通用的操作方法,我们可以把它设计成事件监听器,像通知,消息这些模块都可以这样设计。
3.1 事件源
@Getter
 @Builder(toBuilder = true)
 public class OrderEvent {
   private String msg;
 }
3.2 事件处理程序
@Component
 public class OrderEventListener {
   @EventListener
   public void handleOrderEvent(OrderEvent event) {
     System.out.println("我监听到了handleOrderEvent发布的message为:" + event.getMsg());
   }
 }
3.3 事件触发
@Service
 public class OrderService {
   @Autowired
   private ApplicationContext context;
  public void publishOrder() {
     context.publishEvent(OrderEvent.builder().msg("建立订单").build());
   }
 }
直接测试事件处理程序
@RunWith(SpringRunner.class)
 @SpringBootTest
 public class SecurityApplicationTests implements ApplicationContextAware {
   private ApplicationContext context = null;
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
     this.context = applicationContext;
   }
   @Test
   public void listener() {
     context.publishEvent(OrderEvent.builder().msg("测试方法").build());
   }
测试业务代码
由于@Service也是spring组件 ,所以它里面的事件处理程序也会被注入,这时直接注入业务对象即可
  @Autowired
   OrderService orderService;
   @Test
   public void listenerOrder() {
     orderService.publishOrder();
   }
  
参考:
滑动验证页面