需求:用户报名成功发送通知
一.首先定义事件的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;
}
三.最后
在报名成功业务之后通过spring上下文对象发送通知
applicationContext.publishEvent(even);
观察者模式(发布订阅模式)?
具体说一下我对观察者模式的理解吧,小白第一次写博客,如有理解偏差的地方,欢迎指出~
直接上图吧
- 可以看到这个UML图,Subject是一个抽象类或者接口,Attach()方法保存了所有观察者,也就是组合了Observer抽象观察者,ConcreteSubject是具体的通知者,ConcreteObserver是具体的观察者,组合了ConcreteSubject,从而接受ConcreteSubject发来的通知。
- 那么观察者模式的适用于什么场景呢?
当一个对象的改变需要同时改变其他对象的时候,并且它不知道具体有多少对象有所改变时
就好像一个订单提交成功,可能要减库存,计算运费,用户增加积分等等操作 - 优点?
我认为就是解耦,体现了依赖倒置的原则,哈哈。 - 缺点?
可以看到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
来源:oschina
链接:https://my.oschina.net/u/4255345/blog/4298046