首先假如有这么个场景用户下单之后的操作 订单校验 ,和发送短信操作 平常会写几个service 或者biz 耦合性还是太高于是话不多说 看下面操作
/**
* 注入ApplicationContext用来发布事件
*/
private final ApplicationContext applicationContext;
public String buyOrder(String orderId) {
long start = System.currentTimeMillis();
// 1.查询订单详情
//...............
// 2.检验订单价格 (===>同步处理)
applicationContext.publishEvent(new OrderProductEvent(this, orderId));
// 3.短信通知 (===>异步处理)
applicationContext.publishEvent(new MsgEvent(orderId));
long end = System.currentTimeMillis();
log.info("任务全部完成,总耗时:({})毫秒", end - start);
return "购买成功";
}
我们先来说同步处理 继承 ApplicationEvent这个接口 重写这个方法 给自己要到属性赋值
@ToString
public class OrderProductEvent extends ApplicationEvent {
/**
* 该类型事件携带的信息
*/
private String orderId;
public OrderProductEvent(Object source, String orderId) {
super(source);
this.orderId = orderId;
}
}
一下就是真正的业务实现区域
@Slf4j
@Component
public class OrderProductListener implements ApplicationListener<OrderProductEvent> {
/** 使用 onApplicationEvent 方法对消息进行接收处理 */
@SneakyThrows
@Override
public void onApplicationEvent(OrderProductEvent event) {
//一系列业务操作
String orderId = event.getOrderId();
long start = System.currentTimeMillis();
Thread.sleep(2000);
long end = System.currentTimeMillis();
log.info("{}:校验订单商品价格耗时:({})毫秒", orderId, (end - start));
}
}
===========接下来再来说说 异步
这里需要用到满参构造方法 是为了使用的时候 赋值
@Data
@AllArgsConstructor
public class MsgEvent {
/** 该类型事件携带的信息 */
public String orderId;
}
然后通过一个注解 @EventListener来监听一系列你所需要的操作
@Slf4j
@Component
public class MsgListener {
@Async
@SneakyThrows
@EventListener(MsgEvent.class)
public void sendMsg(MsgEvent event) {
String orderId = event.getOrderId();
long start = System.currentTimeMillis();
log.info("开始发送短信");
log.info("开始发送邮件");
Thread.sleep(4000);
long end = System.currentTimeMillis();
log.info("{}:发送短信、邮件耗时:({})毫秒", orderId, (end - start));
}
}
最后像一些本身就是监听器或者是拦截器的类 咱们使用 Spring工具类来解耦合不需要注入Applicationcontext
我把这个工具类贴下面
package com.najie.activiti.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author 7
* @date 2022/9/22 13:46
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
/**
* 应用上下文赋值
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
我们再来看看 业务场景实际应用