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();
}
参考:
滑动验证页面