请出主角:Spring当中的事件机制
没错,本节主要讲的是Spring中事件机制:ApplicationEventPublisher,实现监听ApplicationEvent,最后利用事件通知实现通知实现异步操作
1、为什么要实现异步操作
- 在微服务的情况下,多个服务互相调用,及其耗时,当我们不需要此操作返回时,可以异步执行,调用接口,该接口快速返回,减少接口响应时长。
- 代码逻辑性清晰,对于需要多个异步操作的可以实现事件的统一管理,不用创建线程池,减少资源的消耗
2、编程过程中有哪些可以去异步执行的
- 所有耗时、且不需要返回的函数
- 比如记录日志操作、发送邮件、短信等操作
代码展示(先实战、后原理)
假如我们现在有一个需求,购买会员操作!先来分析具体步骤:
1、在会员用户列表添加该用户(代表该用户已经具有会员标示)
2、发送具体会员的权益
3、给用户添加积分操作
4、发送短信通知
假如有上四步,那么我们可以将发送短信通知作为异步操作。
第一步,创建事件
public class SendMessageEvent extends ApplicationEvent { private SendMessageEventDto sendMessageEventDto; public SendMessageEvent(Object source) { super(source); } public SendMessageEvent(Object source,SendMessageEventDto dto){ super(source); this.sendMessageEventDto = dto; } public SendMessageEventDto getDto(){ return sendMessageEventDto; } public void setDto(SendMessageEventDto dto){ this.sendMessageEventDto = dto; } public class SendMessageEventDto{ /** * 手机号 */ private Integer userId; /** * 手机号 */ private String mobile; /** * 短信模板参数数据体 */ private String data; public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } } }
上面代码中首先定义发送短信的一个实体(SendMessageEventDto),将这个实体交给定义的事件管理(SendMessageEvent),该事件继承spring的ApplicationEvent
第二步,将事件通过spring发布,由spring监听该事件
@Autowired private ApplicationEventPublisher applicationEventPublisher; /** * 组装数据体异步发送短信 * @param mobile 手机号 * @param userId 用户ID * @param jsonObject 短信所需参数 */ public void publishMessage(String mobile,Integer userId,JSONObject jsonObject){ SendMessageEvent event = new SendMessageEvent(this); SendMessageEvent.SendMessageEventDto dto = event.new SendMessageEventDto(); dto.setData(jsonObject.toString()); //具体业务的数据体 dto.setMobile(mobile); dto.setUserId(userId); event.setDto(dto); //将事件交给spring监听 applicationEventPublisher.publishEvent(event); }
第三步,让具体业务持有该事件,并设置被监听状态
public interface SendMessageEventListener { //发送短信 void sendMessage(SendMessageEvent sendMessageEvent); }
@Component public class SendMessageEventListenerImpl implements SendMessageEventListener { private Logger logger = LoggerFactory.getLogger(SendMessageEventListenerImpl.class); @Autowired private MiniProgramClient miniProgramClient; @Override @Async @EventListener public void sendMessage(SendMessageEvent sendMessageEvent) { try { SendMessageEvent.SendMessageEventDto dto = sendMessageEvent.getDto(); logger.error("发送短信通知开始 -> 数据体为 -> "+ JSON.toJSONString(dto)); MarketMessageDto messageDto = new MarketMessageDto(); messageDto.setUserId(dto.getUserId()); messageDto.setData(dto.getData()); messageDto.setMobile(dto.getMobile()); //调用短信服务,发送短信 miniProgramClient.sendMarketMsg(messageDto); }catch (Exception e){ e.getMessage(); e.printStackTrace(); } } }
这里特别注意的是,必须在需要被监听的方法上加上 @EventListener, 然后开启异步 @Async
演示调用,大功告成
public static void main(String[] args) { //创建会员逻辑开始 //1、创建会员用户 //2、发送会员权益 //3、给用户添加积分 //4发送短信 publishMessage("176********",7465388,具体业务参数的json) //返回结果 return "开通会员成功"; }
OK,到这里就大功告成了,整体流程就是这样,这样当执行到给用户添加积分之后,就可直接返回成功,无须等待发送短信操作。
特别注意:在springBoot项目中使用的话,需要在启动类当中加入注解@EnableAsync
博文转载自掘金博文:
https://juejin.cn/post/6985049438540529694