• 设计模式【消息事件篇】


    1.基于cmq消息事件处理模式,进行消息处理

    ①抽象消息接口

    public interface BenefitMsgHandler {
    
        /**
         * 消息处理器名称
         *
         * @return
         */
        String getName();
    
        /**
         * 消息处理器执行顺序
         *
         * @return
         */
        Integer getOrder();
    
        /**
         * 处理消息
         *
         * @param benefitTaskMsg 消息数据
         */
        void handleMsg(BenefitTaskMsg benefitTaskMsg);
    
        /**
         * 校验任务编码
         *
         * @param benefitTaskMsg 消息数据
         * @return
         */
        boolean checkMsgType(BenefitTaskMsg benefitTaskMsg);
    }

    ②抽象消息模型

    public abstract class AbstractBenefitMsgHandler implements BenefitMsgHandler {
    
        @Autowired
        protected BenefitMsgHandlerManager benefitMsgHandlerManager;
        protected String name;
        protected Integer order = 100;
    
        @PostConstruct
        protected void init() {
            this.benefitMsgHandlerManager.registerHandler(this);
            this.name = this.getClass().getName();
        }
    
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public Integer getOrder() {
            return this.order;
        }
    
        /**
         * 处理消息
         *
         * @param benefitTaskMsg 消息
         */
        @Override
        public abstract void handleMsg(BenefitTaskMsg benefitTaskMsg);
    
        /**
         * 校验消息类型
         *
         * @param benefitTaskMsg 消息实体
         * @return
         */
        @Override
        public abstract boolean checkMsgType(BenefitTaskMsg benefitTaskMsg);
    
    }

    ③ 通用消息处理器

    @Slf4j
    @Component
    public class BenefitMsgHandlerManager {
    
        /**
         * 第三方对接任务处理器
         */
        private CopyOnWriteArrayList<BenefitMsgHandler> benefitMsgHandlers = new CopyOnWriteArrayList<>();
    
        /**
         * 注册第三方对接任务处理器
         *
         * @param benefitMsgHandler
         */
        public void registerHandler(BenefitMsgHandler benefitMsgHandler) {
            //1.注册
            this.benefitMsgHandlers.add(benefitMsgHandler);
            //2.排序
            if (!CollectionUtils.isEmpty(benefitMsgHandlers)) {
                benefitMsgHandlers.sort(Comparator.comparing(BenefitMsgHandler::getOrder));
            }
        }
    
        /**
         * 第三方对接任务处理
         *
         * @param benefitTaskMsg
         */
        public void handleMsg(BenefitTaskMsg benefitTaskMsg) {
            //消息处理器为空直接返回
            if (CollectionUtils.isEmpty(benefitMsgHandlers)) {
                log.info("handleMsg failed , benefit msg handler is empty! ");
                return;
            }
            //处理消息
            for (BenefitMsgHandler benefitMsgHandler : benefitMsgHandlers) {
                try {
                    if (benefitMsgHandler.checkMsgType(benefitTaskMsg)) {
                        log.info("handle benefit msg, param={}, handler={}", JSONObject.toJSONString(benefitTaskMsg), benefitMsgHandler.getName());
                        benefitMsgHandler.handleMsg(benefitTaskMsg);
                        return;
                    }
                } catch (Exception e) {
                    log.error("handle benefit msg, param={}, task={}", JSONObject.toJSONString(benefitTaskMsg), benefitMsgHandler.getName(), e);
                }
            }
        }
    }

    ④ 特定消息处理器--奖励发放

    @Slf4j
    @Component
    public class BenefitMsgHandler4CompleteReward extends AbstractBenefitMsgHandler {
    
        @Autowired
        private RewardHandlerManager rewardHandlerManager;
    
        @Override
        public void handleMsg(BenefitTaskMsg benefitTaskMsg) {
            log.info("BenefitMsgHandler4CompleteReward begin: benefitTaskMsg={}", benefitTaskMsg);
            BenefitTaskRecord benefitTaskRecord = JSON.parseObject(benefitTaskMsg.getData(), BenefitTaskRecord.class);
            rewardHandlerManager.completeReward(benefitTaskRecord, false);
        }
    
        @Override
        public boolean checkMsgType(BenefitTaskMsg benefitTaskMsg) {
            //奖励发放
            if (StringUtils.equals(benefitTaskMsg.getMsgType(), BenefitMsgTypeEnum.COMPLETE_REWARD.getMsgType())) {
                return true;
            }
            return false;
        }
    }

    ⑤监听消息处理

    @Slf4j
    @Component
    public class CmqListenerService {
        @Autowired
        private BenefitMsgHandlerManager benefitMsgHandlerManager;
    
        /**
         * 任务自产消息处理
         *
         * @param msg
         */
        @CmqListener(queue = "${cmq.topic.queue.benefit.task}")
        public void benefitMsgHandlerManager(String msg) {
            log.info("benefitTaskEventHandle:msg={}", msg);
            try {
                BenefitTaskMsg benefitTaskMsg = JSON.parseObject(msg, BenefitTaskMsg.class);
                if (benefitTaskMsg == null) {
                    log.error("benefitTaskEventHandle:msg is invalid");
                }
                benefitMsgHandlerManager.handleMsg(benefitTaskMsg);
            } catch (Exception e) {
                log.error("benefitTaskEventHandle:exception:msg={}", msg, e);
            }
        }
    
    
    }
  • 相关阅读:
    (30)导入时如何定制spring-boot依赖项的版本【转载】【从零开始学Spring Boot】
    (29)Spring boot 文件上传(多文件上传)【从零开始学Spring Boot】
    (28)SpringBoot启动时的Banner设置【从零开始学Spring Boot】
    POSIX 消息队列相关问题
    linux系统的7种运行级别
    如何判断是否开启超线程
    (26)改变自动扫描的包【从零开始学Spring Boot】
    (24)Spring Boot环境变量读取和属性对象的绑定【从零开始学Spring Boot】
    (25)Spring Boot使用自定义的properties【从零开始学Spring Boot】
    《将博客搬至CSDN》
  • 原文地址:https://www.cnblogs.com/antonyhubei/p/16113031.html
Copyright © 2020-2023  润新知