设计模式【消息事件篇】
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); } } }