在当前微服务项目体系中,不同服务之间的通信功能十分重要,之前有一个项目选择了kafka做为技术选型.所以写个博客记录一下大概的工作业务步骤. 在实现的过程中,kafka的搭建基本上没有什么难度,关键在于不同的消息类型之间要进行不同的业务逻辑处理,在实际项目中使用了策略模式来解决这个问题
1.首先下载依赖,搭建配置文件,这些是直接上网查询就行,不用强行记录
2.新建一个接口类
/**
* @description:自定义的kafka 抽象类
* @author :AT
* @date : 2022/6/10 2:51 下午
*/
public interface MyKafkaHandler {
/**
* 注册
* @param baseMessage
*/
void registerUser(BaseMessage baseMessage);
/**
* 支付
* @param baseMessage
*/
void payOrder(BaseMessage baseMessage);
/**
* 处理积分
* @param baseMessage
*/
void processingPoints(BaseMessage baseMessage);
3. 新建一个策略模式工厂类
/**
* @author :AT
* @description: 策略模式工厂类
* @date : 2022/6/10 2:50 下午
*/
public class MyFactoryHashMap {
private static HashMap<String, MyKafkaHandler> handlerHashMap = new HashMap<>();
/**
* 在初始化具体 MyKafkaHandler 子类的时候,将子类实现注册到 map中
*
* @param type
* @param myKafkaHandler
*/
public static void registerHandler(String type, MyKafkaHandler myKafkaHandler) {
handlerHashMap.put(type, myKafkaHandler);
}
/**
* 通过type 获取子类中的对象的实现类
*
* @param type
*/
public static MyKafkaHandler getHandlerByType(String type) {
return StrUtil.isNotEmpty(type) && handlerHashMap.containsKey(type) ? handlerHashMap.get(type) : null;
}
}
4.定义几个接口的实现类 并实现上面定义的接口 和InitializingBean 类,并在afterPropertiesSet 方法中将当前类的 type存到策略模式的工厂中
/**
* @author :AT
* @date : 2022/6/10 3:15 下午
*/
@Slf4j
@Component
public class PayOrderHandler implements MyKafkaHandler, InitializingBean {
/**
* 注册
*
* @param baseMessage
*/
@Override
public void registerUser(BaseMessage baseMessage) {
}
/**
* 支付
*
* @param baseMessage
*/
@Override
public void payOrder(BaseMessage baseMessage) {
log.info("----进入接口payOrder------"+baseMessage.getId());
}
/**
* 添加积分
*
* @param baseMessage
*/
@Override
public void processingPoints(BaseMessage baseMessage) {
}
@Override
public void afterPropertiesSet() throws Exception {
MyFactoryHashMap.registerHandler(MyKafkaTypeEnum.PAY_ORDER.name(), this);
}
/**
* @author :AT
* @date : 2022/6/10 3:18 下午
*/
@Slf4j
@Component
public class ProcessingPointsHandler implements MyKafkaHandler, InitializingBean {
/**
* 注册
*
* @param baseMessage
*/
@Override
public void registerUser(BaseMessage baseMessage) {
}
/**
* 支付
*
* @param baseMessage
*/
@Override
public void payOrder(BaseMessage baseMessage) {
}
/**
* 添加积分
*
* @param baseMessage
*/
@Override
public void processingPoints(BaseMessage baseMessage) {
log.info("-----处理积分------"+baseMessage.getId());
}
@Override
public void afterPropertiesSet() throws Exception {
MyFactoryHashMap.registerHandler(MyKafkaTypeEnum.INTEGRAL.name(),this);
}
}
/**
* @author :AT
* @date : 2022/6/10 3:02 下午
*/
@Slf4j
@Component
public class RegisterUserHandler implements MyKafkaHandler , InitializingBean {
/**
* 注册
*
* @param baseMessage
*/
@Override
public void registerUser(BaseMessage baseMessage) {
log.info("-----接收消息处理注册---->"+baseMessage.getId());
}
/**
* 支付
*
* @param baseMessage
*/
@Override
public void payOrder(BaseMessage baseMessage) {
}
/**
* 添加积分
*
* @param baseMessage
*/
@Override
public void processingPoints(BaseMessage baseMessage) {
}
@Override
public void afterPropertiesSet() throws Exception {
MyFactoryHashMap.registerHandler(MyKafkaTypeEnum.REGISTER.name(),this);
}
}
- 其他需要的两个常量类可以自定义
/**
* @author :AT
* @date : 2022/6/10 3:06 下午
* @description: 类型的枚举
*/
@Getter
@AllArgsConstructor
public enum MyKafkaTypeEnum {
REGISTER("注册"),
PAY_ORDER("支付"),
INTEGRAL("积分");
private String description;
/**
* 根据名字返回 枚举类型
* @param name
* @return
*/
public static MyKafkaTypeEnum resultEnumByName(String name){
if (StrUtil.isEmpty(name)) {
return null;
}
for (MyKafkaTypeEnum value : values()) {
if (value.name().equals(name)) {
return value;
}
}
return null;
}
/**
* @author :AT
* @date : 2022/6/10 2:59 下午
*/
@AllArgsConstructor
@Data
public class BaseMessage {
private String id;
}
- 测试验证工厂模式是否生效,由于本地没有搭建kafka的环境.所以用controller模拟消息推送
/**
* 根据ID获取UserInfo 模仿
* @param id
* @return
* @throws Exception
*/
@GetMapping("/imitateKafkaMessage")
public ResultVo imitateKafkaMessage(@RequestParam String id) {
//模拟通过kafka发送消息 通过 BaseMessage ID获取 消息对象本身
// 这里 假设获取 用户role ,其实逻辑是一样的 只是换一个不同的对象
Role role = roleService.getById(id);
if (Objects.nonNull(role)&& StrUtil.isNotEmpty(role.getRoleName())) {
MyKafkaTypeEnum myKafkaTypeEnum = MyKafkaTypeEnum.resultEnumByName(role.getRoleName());
if (Objects.nonNull(myKafkaTypeEnum)) {
BaseMessage baseMessage = new BaseMessage(id);
MyFactoryHashMap.getHandlerByType(myKafkaTypeEnum.name()).registerUser(baseMessage);
}
}
return new ResultVo<>(StatusCodeEnum.SUCCESS_CODE.getCode(), "", null);
}
当ID为4的时候,输出结果为
说明进入到了注册用户的具体实现类,当ID为5的时候,却不会打印任何数据
数据库的ID与对应的值