用策略模式 + 责任链模式+Nacos实现多层业务逻辑校验
nacos
Nacos是由阿里巴巴开源的服务治理中间件,集成了动态服务发现、配置管理和服务元数据管理功能,广泛应用于微服务架构中,简化服务治理过程。
项目地址:https://gitcode.com/gh_mirrors/na/nacos
免费下载资源
·
设计实现简述
业务需求里校验环节几乎是必须的,对于复杂的业务还会出现层层校验。为了保证不同校验逻辑,可以做到动态可插拔。同时希望后期的扩展性可以更好。
利用策略模式 + 责任链模式对业务校验设计也可以向上声明一个接口,内部提供好校验方法。然后在执行校验时,以责任链的形式一个一个去校验。再基于Nacos提供的一个配置的动态刷新去实现,指定好整体校验链,需要改变时,只需要去修改Nacos中的配置文件即可。
代码示例
示例背景简介
本次示例背景为:短信平台在发送用户短信前的层层校验。总体包括:校验客户的apikey是否合法、校验请求的ip地址是否是白名单、校验短信的签名、校验短信的模板、校验手机号的格式合法性、校验客户剩余的金额是否充足。
定义校验实体
package com.cyx.sms.domain.vo;
import lombok.Data;
import java.io.Serializable;
/**
* 发短信的实体类
*/
@Data
public class CheckEsmObj implements Serializable {
/**
* 手机号
*/
private String mobile;
/**
* apikey
*/
private String apikey;
/**
* ip
*/
private String ip;
/**
* 短信签名
*/
private String sign;
/**
* 短信模板
*/
private String template;
/**
* 余额
*/
private String fee;
}
准备校验的父接口&实现类
利用策略模式设计公共接口和各个实现类
父接口
package com.cyx.sms.service;
import com.cyx.sms.domain.vo.CheckEsmObj;
/**
*
* 做策略模式的父接口
*/
public interface CheckFilter {
/**
* 定义校验统一校验方法名
* @param checkEsmObj
*/
void check(CheckEsmObj checkEsmObj);
}
6个校验的实现类
第一个实现类:校验客户的apikey是否合法
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验客户的apikey是否合法
*/
@Service(value = "apikey")
@Slf4j
public class ApiKeyCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验apikey】 校验"+checkEsmObj.getApikey()+"通过");
}
}
第二个实现类:校验请求的ip地址是否是白名单
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验请求的ip地址是否是白名单
*/
@Service(value = "ip")
@Slf4j
public class IPCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验ip】 校验"+checkEsmObj.getIp()+"通过");
}
}
第三个实现类:校验短信的签名
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验短信的签名
*/
@Service(value = "sign")
@Slf4j
public class SignCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验签名】 校验"+checkEsmObj.getSign()+"通过");
}
}
第四个实现类:校验短信的模板
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验短信的模板
*/
@Service(value = "template")
@Slf4j
public class TemplateCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验模板】 校验"+checkEsmObj.getTemplate()+"通过");
}
}
第五个实现类:校验手机号的格式合法性
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验手机号的格式合法性
*/
@Service(value = "mobile")
@Slf4j
public class MobileCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验手机号】 校验"+checkEsmObj.getMobile()+"通过");
}
}
第六个实现类:校验客户剩余的金额是否充足
package com.cyx.sms.service.impl;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 校验客户剩余的金额是否充足
*/
@Service(value = "fee")
@Slf4j
public class FeeCheckFilter implements CheckFilter {
@Override
public void check(CheckEsmObj checkEsmObj) {
log.info("【接口模块-校验客户余额】校验"+checkEsmObj.getFee()+"通过");
}
}
准备上下文对象
利用责任链模式,实现整个校验链时,直接获取到Context上下文对象即可
package com.cyx.sms.boot;
import com.cyx.sms.domain.vo.CheckEsmObj;
import com.cyx.sms.service.CheckFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 上下文对象
* @RefreshScope注解可在不更新代码的情况下,动态刷新nacos配置信息
*/
@Component
@RefreshScope
public class CheckFilterContext {
// Spring的IOC会将对象全部都放到Map集合中
// 基于4.x中Spring提供的反省注解,基于Map拿到需要的类型对象即可
@Autowired
private Map<String, CheckFilter> checkFiltersMap;
// 基于Nacos获取到执行的顺序和需要执行的校验对象
// 未配置时,执行如下默认的校验项和校验顺序
@Value("${filters:ip,apikey,sign,template,mobile,fee}")
private String filters;
/**
* 当前check方法用于管理校验链的顺序
*/
public void check(CheckEsmObj checkEsmObj){
//1. 将获取到filters基于,做切分
String[] filterArray = filters.split(",");
//2. 遍历数组即可
for (String filter : filterArray) {
CheckFilter checkFilter = checkFiltersMap.get(filter);
checkFilter.check(checkEsmObj);
}
}
}
Nacos配置里准备顺序
# 校验策略的执行内容和顺序 apikey,ip,sign,template,mobile,fee
filters: apikey,ip,sign,template,mobile,fee
接口使用
package com.cyx.sms.controller;
import com.cyx.sms.boot.CheckFilterContext;
import com.cyx.sms.domain.vo.CheckEsmObj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/checkFilter")
public class TestController
{
@Autowired
private CheckFilterContext checkFilterContext;
/**
* 校验链
*/
@PostMapping
public void testCheckFilter(@RequestBody CheckEsmObj checkEsmObj)
{
System.out.println("====================================");
checkFilterContext.check(checkEsmObj);
}
}
请求与结果
GitHub 加速计划 / na / nacos
123
24
下载
Nacos是由阿里巴巴开源的服务治理中间件,集成了动态服务发现、配置管理和服务元数据管理功能,广泛应用于微服务架构中,简化服务治理过程。
最近提交(Master分支:4 个月前 )
762303b9
* [ISSUE #12970] Fix NamingMetadataManager.removeInstanceMetadata() error
fix #12970
* Update NamingMetadataManagerTest.java 4 天前
05561813
* fix type search on mysql model
* 灰度模型迁移程序并发&迁移不落历史表
* Config migrate executor times
* 1.Config migrate executor times
2. history comparation optimize
* 1.Config migrate executor times
2. history comparation optimize
* checkstyle 4 天前
更多推荐
已为社区贡献2条内容
所有评论(0)