• 【java框架】SpringBoot(11) SpringBoot利用监听事件,实现异步操作


    请出主角: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

  • 相关阅读:
    GDB Practice
    GCC常用命令
    使用VS2010 C#编写ActiveX控件
    [.NET] 使用 .NET Framework 開發 ActiveX Control
    VC2005开发MFC ActiveX控件
    Register DLL and OCX
    COM组件开发实践
    Java Invoke C and C++ Using JNI
    Unable to cast object of type 'System.Int32' to type 'System.String'.
    SharePoint wiki 分类获取所有的
  • 原文地址:https://www.cnblogs.com/yif0118/p/15969490.html
Copyright © 2020-2023  润新知