1、什么是责任链设计模式:
    当客户端发起一个请求,需要多个对象对请求做处理,同时这个处理对象对请求的处理顺序也是有要求的,而客户端不需要知道具体的处理对象;这样就实现了请求者与实现者的解耦,并且在客户端可以实现动态的组合职责链,使编程更具灵活性。

    2、责任链设计模式类结构图
    抽象处理者角色(Handler):
    定义一个处理请求的抽象类,里边一般设置有三个部分,一个是处理请求,另一个是获取下个处理器,调用下一个处理器处理请求的方法(因为每个处理器都要调用,所以将其放到抽象类中);

    具体处理者角色(ConcreteHandler):
    具体处理者接到请求后,做两件事,一是处理请求,而是调用下个处理器处理请求。

    3、优缺点:
    优点:动态组合,请求者与接受者解耦;
    动态组合:责任链模式会将功能分散到多个单独的责任对象当中,然后在使用时动态组合形成链,从而可以灵活地分配职责对象,也可以灵活地添加或改变对象职责。

    请求者与接收者解耦:请求者不需要知道接受者,也不需要知道如何处理,每个职责对象只负责自己的职责范围,其他的交给后继者,各个组件完全解耦。

    缺点:这样在处理某个功能请求的过程中就会产生大量的细粒度职责对象,但是这样的缺点也是优点,提高了代码的复用性。

    4、应用场景

    在网关作为微服务程序的入口,拦截客户端所有的请求实现权限控制 ,比如先判断Api接口限流、黑名单、用户会话、参数过滤。
    Api接口限流→黑名单拦截→用户会话→参数过滤

    抽象角色:

    1. public abstract class GatewayHandler {
    2. protected GatewayHandler nextGatewayHandler;
    3. /**
    4. * 处理业务逻辑
    5. *
    6. * @return true 表示继续执行 false表示不继续执行..
    7. */
    8. public abstract void service();
    9. public void setHandler(GatewayHandler gatewayHandler) {
    10. this.nextGatewayHandler = gatewayHandler;
    11. }
    12. protected void nextService(){
    13. if(nextGatewayHandler!=null){
    14. nextGatewayHandler.service();;
    15. }
    16. }
    17. }

    具体实现者:

    1. @Component
    2. public class CurrentLimitHandler extends GatewayHandler {
    3. @Override
    4. public void service() {
    5. System.out.println("第一关网关限流判断....");
    6. nextService();
    7. }
    8. }
    9. @Component
    10. public class BlacklistHandler extends GatewayHandler {
    11. @Override
    12. public void service() {
    13. System.out.println("第二关黑名单拦截判断....");
    14. nextService();
    15. }
    16. }
    17. @Component
    18. public class ConversationHandler extends GatewayHandler {
    19. @Override
    20. public void service() {
    21. System.out.println("第三关用户会话拦截判断....");
    22. nextService();
    23. }
    24. }
    25. @Component
    26. public class ConversationHandler extends GatewayHandler {
    27. @Override
    28. public void service() {
    29. System.out.println("第三关用户会话拦截判断....");
    30. nextService();
    31. }
    32. }

    GatewayHandlerService:

    1. @Component
    2. public class GatewayHandlerService {
    3. @Autowired
    4. private GatewayHandlerMapper gatewayHandlerMapper;
    5. private GatewayHandler firstGatewayHandler;
    6. public GatewayHandler getDbGatewayHandler() {
    7. if (firstGatewayHandler != null) {
    8. return firstGatewayHandler;
    9. }
    10. // 1.获取第一个GatewayHandler信息
    11. GatewayHandlerEntity firstGatewayHandlerEntity = gatewayHandlerMapper.getFirstGatewayHandler();
    12. if (firstGatewayHandlerEntity == null) {
    13. return null;
    14. }
    15. // 2.获取第一个firstGatewayHandler spring容器中的id
    16. String handlerBeanId = firstGatewayHandlerEntity.getHandlerId();
    17. // 3.从spring容器中获取对应的对象 firstGatewayHandler
    18. GatewayHandler firstGatewayHandler = SpringUtils.getBean(handlerBeanId, GatewayHandler.class);
    19. // 4.使用white循环 设置下一个节点 同时定义循环遍历临时对象
    20. GatewayHandler tempGatewayHandler = firstGatewayHandler;
    21. // 5.获取下一个节点
    22. String nextHandlerBeanId = firstGatewayHandlerEntity.getNextHandlerId();
    23. while (!StringUtils.isEmpty(nextHandlerBeanId)) {
    24. GatewayHandlerEntity nextGatewayHandlerEntity = gatewayHandlerMapper.getByHandler(nextHandlerBeanId);
    25. if (nextGatewayHandlerEntity == null) {
    26. break;
    27. }
    28. // 6.从springboot容器获取下一个handler 对象
    29. String tempNextHandlerBeanId = nextGatewayHandlerEntity.getHandlerId();
    30. GatewayHandler nextGatewayHandler = SpringUtils.getBean(tempNextHandlerBeanId, GatewayHandler.class);
    31. // 7.设置当前handler下一个handler对象
    32. tempGatewayHandler.setHandler(nextGatewayHandler);
    33. tempGatewayHandler = nextGatewayHandler;
    34. // 8.循环遍历下一个节点
    35. nextHandlerBeanId = nextGatewayHandlerEntity.getNextHandlerId();
    36. }
    37. this.firstGatewayHandler = firstGatewayHandler;
    38. return firstGatewayHandler;
    39. }
    40. }

    如何调用:

    1. @RestController
    2. public class HandlerController {
    3. @Autowired
    4. private GatewayHandlerService gatewayHandlerService;
    5. @RequestMapping("/client")
    6. public String client() {
    7. GatewayHandler firstGatewayHandler = gatewayHandlerService.getFirstGatewayHandler();
    8. firstGatewayHandler.service();
    9. return "success";
    10. }
    11. }

    总结:
    1.什么是责任链模式
    2.责任链模式应用场景
    3.责任链与链表数据结构关系
    4.基于工厂模式实现责任链
    5.基于数据库实现动态责任链
    6.Java过滤器责任链模式源码分析