代码解耦工具包
注意事项
旧项目慎用
版本是1.10.2-SNAPSHOT 的版本,其中Redis经过了大的改动,需要中台环境是1.10.0以上的版本
简介
- 为什么会有这个工具包,主要还是为了提高代码的扩展性,尤其在系统的业务越来越多了。例如我初始化一个企业,需要做菜单初始化、门户初始化、用户的初始化、角色初始化、部门初始化、套件的安装,这一系列的动作,后续也不知道会不会加。而套件的安装又涉及到用户组、参照项、流程、流水号,想这一部分,如果每次都要改动其中的代码对后续对接的人很复杂,不知道会不会有什么坑,所以就有了这个工具包来把他解耦,当然你说你用MQ也是可以的,就是看个人使用,同一个工程的还是不建议使用MQ的。
- 可以通过定义类型、事件、匹配规则执行指定的方法。
- 可以设置handler的Log日志输出,为什么这样会方便呢,首先是这样统一了一个日志的规范,然后每个业务处理自己的业务逻辑,互不影响,当然业务会有关联的就别尬黑了。
- 支持异步执行
- 支持排重检查(内存、Redis),也支持开发者自己定义排重的方法
- 支持Last执行,指定last的handler会最后执行
- 出现异常会打印错误日志
Maven 依赖
<dependency>
<groupId>cn.flyrise</groupId>
<artifactId>pai-common-message</artifactId>
<version>1.10.2-SNAPSHOT</version>
</dependency>
关键代码说明
//消息的排重,这里可以使用Redis,common包中还提供了内存的
@Bean
public MessageDuplicateChecker messageDuplicateChecker() {
return new MessageRedisDuplicateChecker(redisTemplate);
}
//定义全局的路由规则配置
@Bean
public MessageRouter messageRouter() {
final MessageRouter newRouter = new MessageRouter(messageDuplicateChecker());
newRouter.rule().async(true).handler(new LogHandler()).next();
newRouter.rule().msgType("staff").last(true).async(true).handler(new StaffHandler()).next();
newRouter.rule().async(false).handler(new DeptHandler()).end();
return newRouter;
}
MessageRouterRule.class
关键属性说明msgType
:消息类型event
:事件类型async
:是否异步content
:消息内容rContent
:内容正则匹配last
:是否最后执行
MessageRouter.class
关键属性说明next()
:表示配置继续,如上图我配置的第一个是日志然后最后.next(),然后后面再写了一个企业创建的handler。end()
:表示结束,不会再往下执行了。msgType
:会匹配messageBean中的消息类型然后执行到对应的handler的方法
代码
路由配置
import cn.flyrise.common.api.MessageDuplicateChecker;
import cn.flyrise.common.api.MessageRouter;
import cn.flyrise.common.api.impl.MessageRedisDuplicateChecker;
import cn.flyrise.common.handler.LogHandler;
import cn.flyrise.pai.console.handler.event.CreateEnterpriseHandler;
import cn.flyrise.pai.console.model.constants.UnifyMessageConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
/**
* 统一消息驱动事件配置
*
* @author Y.zc
* @data 2022/10/25 17:20
* @since 1.8.0
*/
@Configuration
public class UnifyMessageConfiguration {
@Resource
private LogHandler logHandler;
@Resource
private RedisTemplate redisTemplate;
@Resource
private CreateEnterpriseHandler createEnterpriseHandler;
@Bean
public MessageDuplicateChecker messageDuplicateChecker() {
return new MessageRedisDuplicateChecker(redisTemplate);
}
@Bean
public MessageRouter messageRouter() {
final MessageRouter newRouter = new MessageRouter(messageDuplicateChecker());
//日志记录
newRouter.rule().async(true).handler(logHandler).next();
//企业创建
newRouter.rule().async(false)
.msgType(UnifyMessageConstants.EnterpriseMsgType.CREATE)
.handler(createEnterpriseHandler)
.end();
return newRouter;
}
}
handler逻辑代码编写
继承AbstractHandler,并实现handler方法就可以了,AbstractHandler支持泛型,注意泛型的使用
@Component
public class LogHandler extends AbstractHandler<String> {
public LogHandler() {
}
public OutMessageBean handle(MessageBean<String> messageBean, Map<String, Object> context) {
this.logger.info("\nLogHandler 接收到请求消息,内容:{}", JSONUtil.toJsonStr(messageBean));
return null;
}
}
@Component
public class DeptHandler extends AbstractHandler<DeptDTO> {
@Override
public OutMessageBean handle(MessageBean<DeptDTO> messageBean, Map<String, Object> context) {
ThreadUtil.sleep(1000);
StaticLog.info("\nDeptHandler 接收到请求消息,内容:{}", JSONUtil.toJsonStr(messageBean));
return new OutMessageBean("dept");
}
}
消息的发送
MessageBean messageBean = new MessageBean<StaffDTO>();
StaffDTO staffDTO = new StaffDTO();
staffDTO.setId("1");
staffDTO.setStaffName("zcy");
staffDTO.setStaffPhone("13711687995");
messageBean.setMsgType("staff");
messageBean.setMsgId("1");
messageBean.setContent(staffDTO);
OutMessageBean out = newRouter.route(messageBean,null);
- msgId 是用来判断是否重复的标识
- msgType 用来匹配路由
结果展示
文档更新时间: 2024-03-25 11:23 作者:朱灿奕