发布于2020-11-19 20:21 阅读(691) 评论(0) 点赞(15) 收藏(4)
责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者
1、当必须按顺序执行多个处理者时,可以使用该模式
2、SpringMVC拦截器的使用
3、网关拦截器使用
public class HandlerChain {
// 持有所有Handler:
private List<Handler> handlers = new ArrayList<>();
public Handler init(){
OneTaskHandler oneTaskHandler = new OneTaskHandler();
TwoTaskHandler twoTaskHandler = new TwoTaskHandler();
ThreeTaskHandler threeTaskHandler = new ThreeTaskHandler();
oneTaskHandler.setNextHandler(twoTaskHandler);
twoTaskHandler.setNextHandler(threeTaskHandler);
return oneTaskHandler;
}
}
public abstract class Handler {
/**下一步执行的任务*/
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
/**任务处理*/
public final void taskProcessing(Task task){
this.taskReport(task);
if(Objects.nonNull(this.nextHandler)){
nextHandler.taskProcessing(task);
}
}
/**从任务中获取能处理的任务级别*/
protected abstract int getTaskLevel();
/**输出任务*/
protected abstract void taskReport(Task task);
}
public class OneTaskHandler extends Handler {
@Override
protected int getTaskLevel() {
return 1;
}
@Override
protected void taskReport(Task task) {
System.out.println("一级任务进行处理");
}
}
public class TwoTaskHandler extends Handler {
@Override
protected int getTaskLevel() {
return 2;
}
@Override
protected void taskReport(Task task) {
System.out.println("二级任务进行处理");
}
}
public class ThreeTaskHandler extends Handler {
@Override
protected int getTaskLevel() {
return 3;
}
@Override
protected void taskReport(Task task) {
System.out.println("三级任务进行处理");
}
}
public class Client {
public static void main(String[] args) {
HandlerChain handlerChain = new HandlerChain();
Handler init = handlerChain.init();
init.taskProcessing(new Task());
}
}
public abstract class GetewayHandlerAbstract {
protected GetewayHandlerAbstract next;
public void setNext(GetewayHandlerAbstract next) {
this.next = next;
}
public final void taskProcess(Object RequestParams) {
if(!this.servicDealWith(RequestParams)){
//TODO 此处可以自行处理
return;
}
if(this.next != null){
this.next.taskProcess(RequestParams);
}
}
/**service进行处理*/
public abstract boolean servicDealWith(Object RequestParams);
}
/**
* api接口限流
*/
public class ApiLimitGetewayHandler extends GetewayHandlerAbstract{
@Override
public boolean servicDealWith(Object RequestParams) {
//使用限流框架、获取使用信号量进行限流
System.out.println("第一步,api接口限流校验");
return true;
}
}
/**
* 黑名单拦截
*/
public class BlacklistGetwayHandler extends GetewayHandlerAbstract{
public boolean servicDealWith(Object RequestParams) {
//从数据库或者缓存中获取数据进行校验
System.out.println("第二步,黑名单拦截校验");
return true;
}
}
/**
* 参数过滤拦截
*/
public class ParamGetwayHandler extends GetewayHandlerAbstract{
public boolean servicDealWith(Object requestParams) {
//从请求的参数中获取参数,进行特殊字符或者敏感词汇进行过滤
System.out.println("第四步,参数过滤拦截");
return true;
}
}
/**
* 用户会话拦截
*/
public class SessionGetwayHandler extends GetewayHandlerAbstract {
public boolean servicDealWith(Object RequestParams) {
//从参数中获取用户的会话是不是又权限操作接口
System.out.println("第三步,用户会话拦截校验");
return true;
}
}
public class GetewayHandlerFactory {
public static GetewayHandlerAbstract GetewayHandler(){
//TODO 像在程序种通过设置order 可以自行拿到Handler之后在进行一次排序
//第一种通过手动自动设置
//api接口限流
GetewayHandlerAbstract apiLimitGetewayHandler = new ApiLimitGetewayHandler();
//黑名单拦截
GetewayHandlerAbstract blacklistGetwayHandler = new BlacklistGetwayHandler();
//用户会话拦截
GetewayHandlerAbstract sessionGetwayHandler = new SessionGetwayHandler();
//参数过滤
GetewayHandlerAbstract paramGetwayHandler = new ParamGetwayHandler();
apiLimitGetewayHandler.setNext(blacklistGetwayHandler);//api接口限流的下一步是黑名单拦截
blacklistGetwayHandler.setNext(sessionGetwayHandler);//黑白拦截的下一步是用户会话拦截
sessionGetwayHandler.setNext(paramGetwayHandler);//用户会话拦截的下一步是参数果过滤拦截
return apiLimitGetewayHandler;
}
}
public abstract class GetewayHandlerAbstract {
protected GetewayHandlerAbstract next;
public void setNext(GetewayHandlerAbstract next) {
this.next = next;
}
public final void taskProcess(Object RequestParams) {
if(!this.servicDealWith(RequestParams)){
//TODO 此处可以自行处理
return;
}
if(this.next != null){
this.next.taskProcess(RequestParams);
}
}
/**service进行处理*/
public abstract boolean servicDealWith(Object RequestParams);
}
/**
* api接口限流
*/
public class ApiLimitGetewayHandler extends GetewayHandlerAbstract{
@Override
public boolean servicDealWith(Object RequestParams) {
//使用限流框架、获取使用信号量进行限流
System.out.println("第一步,api接口限流校验");
return true;
}
}
/**
* 黑名单拦截
*/
public class BlacklistGetwayHandler extends GetewayHandlerAbstract{
public boolean servicDealWith(Object RequestParams) {
//从数据库或者缓存中获取数据进行校验
System.out.println("第二步,黑名单拦截校验");
return true;
}
}
/**
* 参数过滤拦截
*/
public class ParamGetwayHandler extends GetewayHandlerAbstract{
public boolean servicDealWith(Object requestParams) {
//从请求的参数中获取参数,进行特殊字符或者敏感词汇进行过滤
System.out.println("第四步,参数过滤拦截");
return true;
}
}
/**
* 用户会话拦截
*/
public class SessionGetwayHandler extends GetewayHandlerAbstract {
public boolean servicDealWith(Object RequestParams) {
//从参数中获取用户的会话是不是又权限操作接口
System.out.println("第三步,用户会话拦截校验");
return true;
}
}
public interface GetewayDao {
/**
* 根据 handlerId 获取配置项
* @param handlerId
* @return
*/
GetewayEntity getGetewayEntity(Integer handlerId);
/**
* 获取第一个处理者
* @return
*/
GetewayEntity getFirstGetewayEntity();
}
public class GetewayDaoImpl implements GetewayDao{
/**
* 初始化,将枚举中配置的handler 初始化到map中,方便获取
*/
private static Map<Integer, GetewayEntity> getewayEntityHashMap = new HashMap<Integer, GetewayEntity>();
static {
GetewayEnum[] values = GetewayEnum.values();
for (GetewayEnum value : values) {
GetewayEntity getewayEntity = value.getGetewayEntity();
getewayEntityHashMap.put(getewayEntity.getHandlerId(),getewayEntity);
}
}
@Override
public GetewayEntity getGetewayEntity(Integer handlerId) {
return getewayEntityHashMap.get(handlerId);
}
/**
* 获取第一个handler的配置项 枚举
* @return
*/
@Override
public GetewayEntity getFirstGetewayEntity(){
for(Map.Entry<Integer,GetewayEntity> entry : getewayEntityHashMap.entrySet()){
GetewayEntity value = entry.getValue();
// 没有上一个handler的就是第一个
if(value.getParnerHandlerId() == null){
return value;
}
}
return null;
}
}
@Data
public class GetewayEntity {
private Integer handlerId;
private String msg;
private String handlerClassName;
private Integer parnerHandlerId;
private Integer nextHandlerId;
}
/***
CREATE TABLE `handler_task` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`handler_id` INT(11) NULL DEFAULT '0' COMMENT '当前handler的Id',
`msg` INT(11) NULL DEFAULT NULL COMMENT '描述',
`handler_class_name` VARCHAR(50) NULL DEFAULT NULL COMMENT '对用springService的名称或者全类名' COLLATE 'utf8_general_ci',
`parner_handler_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '父级handler的Id' COLLATE 'utf8_general_ci',
`next_nandler_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '下一级别的handler的Id' COLLATE 'utf8_general_ci',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` VARCHAR(50) NULL DEFAULT NULL COMMENT '创建者' COLLATE 'utf8_general_ci',
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`update_by` VARCHAR(50) NULL DEFAULT NULL COMMENT '修改者' COLLATE 'utf8_general_ci'
PRIMARY KEY (`id`) USING BTREE
)
COMMENT='处理任务过程表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB=
;
**/
public enum GetewayEnum {
/**
* 在这里大家需要注意到一个点 api接口限流是第一个处理者 因此没有 prehandlerId,也就是 它的prehandlerId = null
*/
API_HANDLER(new GetewayEntity(1,"api接口限流","chain_of_responsibility.cases.statics.handler.ApiLimitGetewayHandler",null,2)),
BLACKLIST_HANDLER(new GetewayEntity(2,"黑名单拦截","chain_of_responsibility.cases.statics.handler.BlacklistGetwayHandler",1,3)),
SESSION_HANDLER(new GetewayEntity(3,"用户会话拦截","chain_of_responsibility.cases.statics.handler.SessionGetwayHandler",2,4)),
/**
* 这是最后一个处理者,因此没有下一个 nexthandlerId 也就是它的 nexthandlerId = null
*/
PARAM_HANDLER(new GetewayEntity(4,"参数过滤拦截","chain_of_responsibility.cases.statics.handler.ParamGetwayHandler",3,null)),
;
GetewayEntity getewayEntity;
public GetewayEntity getGetewayEntity() {
return getewayEntity;
}
GetewayEnum(GetewayEntity getewayEntity) {
this.getewayEntity = getewayEntity;
}
}
ublic class GetewayHandlerEnumFactory {
private static GetewayDao getewayDao = new GetewayDaoImpl();
public static GetewayHandlerAbstract getFirstGetewayHandler1(){
// 1\. 获取第一处理者 那么那个是第一个处理者呢 prehandlerId == null 的就是第一个handler
GetewayEntity firstGetewayEntity = getewayDao.getFirstGetewayEntity();
GetewayHandlerAbstract firstGetewayHandler = newGetewayHandler(firstGetewayEntity);
if(firstGetewayHandler == null){
return null;
}
setNextGetewayHandler(firstGetewayEntity,firstGetewayHandler);
return firstGetewayHandler;
}
private static void setNextGetewayHandler(GetewayEntity getewayEntity,GetewayHandlerAbstract getewayHandler){
if(getewayHandler != null && getewayEntity != null){
Integer nexthandlerId = getewayEntity.getNextHandlerId();
GetewayEntity nextGetewayEntity = getewayDao.getGetewayEntity(nexthandlerId);
GetewayHandlerAbstract nextGetewayHandler = newGetewayHandler(nextGetewayEntity);
getewayHandler.setNext(nextGetewayHandler);
//递归 设置
setNextGetewayHandler(nextGetewayEntity,nextGetewayHandler);
}
}
/**
* 反射实体化具体的处理者
* @param getewayEntity
* @return
*/
private static GetewayHandlerAbstract newGetewayHandler(GetewayEntity getewayEntity){
if(getewayEntity == null){
return null;
}
String handlerClassName = getewayEntity.getHandlerClassName();
try {
Class<?> clazz = Class.forName(handlerClassName);
return (GetewayHandlerAbstract) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
public class GetewayClient {
public static void main(String[] args) {
GetewayHandlerAbstract firstGetewayHandler = GetewayHandlerEnumFactory.getFirstGetewayHandler1();
Object params = new Object();
firstGetewayHandler.taskProcess(params);
}
}
这只是针对于接口层做了链式处理,责任链真正的思想是链式处理,别被这一个场景给误导,具体真实场景还可以是(WETSV) 算每一个层级,下一个层级依赖上一个层级的数据,WE->WET->WETS->WETSV
责任链模式、 命令模式、 中介者模式和观察者模式用于处理请求发送者和接收者之间的不同连接方式:
责任链通常和组合模式结合使用。 在这种情况下, 叶组件接收到请求后, 可以将请求沿包含全体父组件的链一直传递至对象树的底部。
责任链的管理者可使用命令模式实现。 在这种情况下, 你可以对由请求代表的同一个上下文对象执行许多不同的操作。
还有另外一种实现方式, 那就是请求自身就是一个命令对象。 在这种情况下, 你可以对由一系列不同上下文连接而成的链执行相同的操作。
责任链和装饰模式的类结构非常相似。 两者都依赖递归组合将需要执行的操作传递给一系列对象。 但是, 两者有几点重要的不同之处。
责任链的管理者可以相互独立地执行一切操作, 还可以随时停止传递请求。 另一方面, 各种装饰可以在遵循基本接口的情况下扩展对象的行为。 此外, 装饰无法中断请求的传递。
https://zhuanlan.zhihu.com/p/99334096.
整理不易,记得点个赞,你的支持是我最大的动力
❤️❤️写优质博客 培养优秀思想 ❤️❤️
原文链接:https://blog.csdn.net/qq_25582465/article/details/109766576
作者:你不要惹我
链接:http://www.javaheidong.com/blog/article/823/b974bf2b46ea57b503d0/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!