1、什么是责任链设计模式:
当客户端发起一个请求,需要多个对象对请求做处理,同时这个处理对象对请求的处理顺序也是有要求的,而客户端不需要知道具体的处理对象;这样就实现了请求者与实现者的解耦,并且在客户端可以实现动态的组合职责链,使编程更具灵活性。
2、责任链设计模式类结构图
抽象处理者角色(Handler):
定义一个处理请求的抽象类,里边一般设置有三个部分,一个是处理请求,另一个是获取下个处理器,调用下一个处理器处理请求的方法(因为每个处理器都要调用,所以将其放到抽象类中);
具体处理者角色(ConcreteHandler):
具体处理者接到请求后,做两件事,一是处理请求,而是调用下个处理器处理请求。
3、优缺点:
优点:动态组合,请求者与接受者解耦;
动态组合:责任链模式会将功能分散到多个单独的责任对象当中,然后在使用时动态组合形成链,从而可以灵活地分配职责对象,也可以灵活地添加或改变对象职责。
请求者与接收者解耦:请求者不需要知道接受者,也不需要知道如何处理,每个职责对象只负责自己的职责范围,其他的交给后继者,各个组件完全解耦。
缺点:这样在处理某个功能请求的过程中就会产生大量的细粒度职责对象,但是这样的缺点也是优点,提高了代码的复用性。
4、应用场景
在网关作为微服务程序的入口,拦截客户端所有的请求实现权限控制 ,比如先判断Api接口限流、黑名单、用户会话、参数过滤。
Api接口限流→黑名单拦截→用户会话→参数过滤
抽象角色:
public abstract class GatewayHandler {protected GatewayHandler nextGatewayHandler;/*** 处理业务逻辑** @return true 表示继续执行 false表示不继续执行..*/public abstract void service();public void setHandler(GatewayHandler gatewayHandler) {this.nextGatewayHandler = gatewayHandler;}protected void nextService(){if(nextGatewayHandler!=null){nextGatewayHandler.service();;}}}
具体实现者:
@Componentpublic class CurrentLimitHandler extends GatewayHandler {@Overridepublic void service() {System.out.println("第一关网关限流判断....");nextService();}}@Componentpublic class BlacklistHandler extends GatewayHandler {@Overridepublic void service() {System.out.println("第二关黑名单拦截判断....");nextService();}}@Componentpublic class ConversationHandler extends GatewayHandler {@Overridepublic void service() {System.out.println("第三关用户会话拦截判断....");nextService();}}@Componentpublic class ConversationHandler extends GatewayHandler {@Overridepublic void service() {System.out.println("第三关用户会话拦截判断....");nextService();}}
GatewayHandlerService:
@Componentpublic class GatewayHandlerService {@Autowiredprivate GatewayHandlerMapper gatewayHandlerMapper;private GatewayHandler firstGatewayHandler;public GatewayHandler getDbGatewayHandler() {if (firstGatewayHandler != null) {return firstGatewayHandler;}// 1.获取第一个GatewayHandler信息GatewayHandlerEntity firstGatewayHandlerEntity = gatewayHandlerMapper.getFirstGatewayHandler();if (firstGatewayHandlerEntity == null) {return null;}// 2.获取第一个firstGatewayHandler spring容器中的idString handlerBeanId = firstGatewayHandlerEntity.getHandlerId();// 3.从spring容器中获取对应的对象 firstGatewayHandlerGatewayHandler firstGatewayHandler = SpringUtils.getBean(handlerBeanId, GatewayHandler.class);// 4.使用white循环 设置下一个节点 同时定义循环遍历临时对象GatewayHandler tempGatewayHandler = firstGatewayHandler;// 5.获取下一个节点String nextHandlerBeanId = firstGatewayHandlerEntity.getNextHandlerId();while (!StringUtils.isEmpty(nextHandlerBeanId)) {GatewayHandlerEntity nextGatewayHandlerEntity = gatewayHandlerMapper.getByHandler(nextHandlerBeanId);if (nextGatewayHandlerEntity == null) {break;}// 6.从springboot容器获取下一个handler 对象String tempNextHandlerBeanId = nextGatewayHandlerEntity.getHandlerId();GatewayHandler nextGatewayHandler = SpringUtils.getBean(tempNextHandlerBeanId, GatewayHandler.class);// 7.设置当前handler下一个handler对象tempGatewayHandler.setHandler(nextGatewayHandler);tempGatewayHandler = nextGatewayHandler;// 8.循环遍历下一个节点nextHandlerBeanId = nextGatewayHandlerEntity.getNextHandlerId();}this.firstGatewayHandler = firstGatewayHandler;return firstGatewayHandler;}}
如何调用:
@RestControllerpublic class HandlerController {@Autowiredprivate GatewayHandlerService gatewayHandlerService;@RequestMapping("/client")public String client() {GatewayHandler firstGatewayHandler = gatewayHandlerService.getFirstGatewayHandler();firstGatewayHandler.service();return "success";}}
总结:
1.什么是责任链模式
2.责任链模式应用场景
3.责任链与链表数据结构关系
4.基于工厂模式实现责任链
5.基于数据库实现动态责任链
6.Java过滤器责任链模式源码分析
