Spring整个体系包含着很多有意思的功能点,有可能你还不知道,自己手动去实现一套,不仅麻烦而且耗费时间,可以多了解了解探索发现Spring很多已经弄好的功能点。
ApplicationListener
做什么?
用来监听所修饰的数据,一旦有该类型的数据推送过来,立马被监听到,并且做自己的业务处理
有什么用?
它有点类似MQ的推送订阅。
比如我们有个主流程登录完了之后可能需要发某个短信。
我们可以通过发送短信模版类型的数据异步给订阅该类型的数据去处理。
该类型的方法还支持同步处理。但通常建议你用线程池去做。
总的来讲就是一张这样的图 :
代码实现
数据端
public class OrderModel {
private String orderNo;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
}
包装成一个特定的Event事件
public class OrderApplicationEvent extends ApplicationEvent {
public OrderApplicationEvent(OrderModel orderModel) {
super(orderModel);
}
}
发送端
public class EventCase extends ElabQuestionApplicationTests {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Test
public void test1() throws IOException {
// 业务数据
OrderModel orderModel = new OrderModel();
orderModel.setOrderNo("abcd123");
// 事件包装
OrderApplicationEvent event = new OrderApplicationEvent(orderModel);
// 发送事件
applicationEventPublisher.publishEvent(event);
}
}
消费端 也可以理解为订阅端
比如 物流操作
@Component
public class OrderLogisticsSmsApplicationListener implements ApplicationListener<OrderApplicationEvent> {
@Override
public void onApplicationEvent(OrderApplicationEvent event) {
System.out.println("物流开始处理 " + JSON.toJSONString(event));
}
}
短信操作
@Component
public class OrderSmsApplicationListener implements ApplicationListener<OrderApplicationEvent> {
@Override
public void onApplicationEvent(OrderApplicationEvent event) {
System.out.println("短信开始处理 " + JSON.toJSONString(event));
}
}
返回结果:
物流开始处理 {"timestamp":1587539487365}
短信开始处理 {"timestamp":1587539487365}
如果后续还有其他的操作只需要新增类实现ApplicationListener<OrderApplicationEvent>
接口就行了。
另外关于线程池以及出现异常的拓展
这里可以手动定义线程池,然后后续发布事件操作都会以异步去处理。
@Configuration
public class BeanConfiguration {
private Executor executor = Executors.newSingleThreadExecutor();
@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster() {
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
simpleApplicationEventMulticaster.setTaskExecutor(executor); // 注入线程池
simpleApplicationEventMulticaster.setErrorHandler(new MyErrorHandler()); // 异常处理器
return simpleApplicationEventMulticaster;
}
}
异常处理器
public class MyErrorHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
System.out.println(" 出现异常啦...");
}
}
当然这些场景只适用于一些不太重要的业务异步处理的场景,重要的话可以通过同步去做,同步的话不需要拓展这一部分的定义,默认就是同步。
至于一些原理,可以自行查看。