java+微信小程序结合发布订阅模式实现异步发送订阅消息

和自甴很熟 提交于 2020-08-07 13:27:27

需求:用户报名成功发送通知

一.首先定义事件的even
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApiCyActivityEven {
    /**
     * openId
     */
   private String touser;
    /**
     * 模板id
     */
    private String template_id;
    /**
     * 跳转页面路径
     */
    private String page;
    /**
     * 跳转小程序类型
     */
    private String miniprogram_state;
    /**
     * 语言类型
     */
    private String lang;
    /**
     * 推送文字
     */
    private Map<String, Object> data;

};
二.然后自定义事件监听器
@Component("apiCyActivityListener")
@AllArgsConstructor
@Slf4j
public class ApiCyActivityListener {
    private final WxConfig wxConfig;

    @Async
    @EventListener(ApiCyActivityEven.class)
    @Order(0)
    public void sendActivitySuccess(ApiCyActivityEven even){
        try {
            Map<String, Object> stringObjectMap = sendTemplateMsg(wxConfig.getWxMaService().getAccessToken(), even);
            int errorCode=(Integer)stringObjectMap.get("errcode");
            String errorMessage=stringObjectMap.get("errmsg").toString();
            if(errorCode==0){
                log.info("通知发送成功:"+errorCode+","+errorMessage);
            }else{
                log.error("通知发送失败:"+errorCode+","+errorMessage);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("服务异常!");
        }

    }

}

1.@Async:使用Spring提供的异步执行注解,需要在SpringBoot启动时添加@EnableAsync注解,Spring会为其单独生成一个线程池,从而不影响主线程。Spring异步配置使用的是SimpleAsyncTaskExecutor,可以参考源码。
2.@EventListener()Spring提供事件监听注解,只需要将我们刚才编写的事件even加入到里面即可。

三.发送订阅通知请求

    public static Map<String,Object> sendTemplateMsg(String token, ApiCyActivityEven even){
        String requestUrl="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
        requestUrl = requestUrl.replace("ACCESS_TOKEN", token);
        String templateJson = JSON.toJSONString(even);
        String result = HttpUtil.sendPost(requestUrl, templateJson);
        Map<String,Object> maps= JSON.parseObject(result,Map.class);
        return maps;
    }

微信api调用地址:
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html

三.最后

在报名成功业务之后通过spring上下文对象发送通知

applicationContext.publishEvent(even);
观察者模式(发布订阅模式)?

具体说一下我对观察者模式的理解吧,小白第一次写博客,如有理解偏差的地方,欢迎指出~
直接上图吧
在这里插入图片描述

  1. 可以看到这个UML图,Subject是一个抽象类或者接口,Attach()方法保存了所有观察者,也就是组合了Observer抽象观察者,ConcreteSubject是具体的通知者,ConcreteObserver是具体的观察者,组合了ConcreteSubject,从而接受ConcreteSubject发来的通知。
  2. 那么观察者模式的适用于什么场景呢?
    当一个对象的改变需要同时改变其他对象的时候,并且它不知道具体有多少对象有所改变时
    就好像一个订单提交成功,可能要减库存,计算运费,用户增加积分等等操作

  3. 优点?
    我认为就是解耦,体现了依赖倒置的原则,哈哈。
  4. 缺点?
    可以看到Subject主题虽然将Observer抽象观察者ConcreteSubject具体的通知者解耦了,但是Subject抽象通知者还是依赖于Observer抽象观察者
    那么怎么解决呢?那么又要引申出来一个设计模式,委派模型
    java实现委派模型,可参考:
    https://blog.csdn.net/yanshujun/article/details/6494447



applicationContext.publishEvent(even)
底层结合观察者设计模式和委派模型
可参考:https://blog.csdn.net/ignorewho/article/details/85603920

思考:
@Async默认使用的SimpleAsyncTaskExecutor线程池会发生OOM?
可参考:https://blog.csdn.net/ignorewho/article/details/85603920

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!