Java设计模式-责任链模式
          目录
          
        
        
      设计模式-责任链模式
通过模式数据库来配置责任链顺序,运用案例,网关需要过滤api限制;黑名单;参数过滤;session过滤等相关功能
定义抽象handler
package com.example.spring.boot.test.chainresponsibility.handle;
public abstract class GatewayHandle {
    public GatewayHandle next;
    public void setNext(GatewayHandle next){
        this.next = next;
    }
    public abstract void service();
}该抽象类里面包含一个next节点,可以理解为单向链表数据结构。
各个任务组件子类
ApiLimitGatewayHandle
package com.example.spring.boot.test.chainresponsibility.handle.impl;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class ApiLimitGatewayHandle extends GatewayHandle {
    @Override
    public void service() {
        System.out.println("api limit......");
        if(this.next != null){
            this.next.service();
        }
    }
}BlacklistGetwayHandler
package com.example.spring.boot.test.chainresponsibility.handle.impl;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class BlacklistGetwayHandler extends GatewayHandle {
    @Override
    public void service() {
        System.out.println("black list......");
        if(this.next != null){
            this.next.service();
        }
    }
}ParamGetwayHandler
package com.example.spring.boot.test.chainresponsibility.handle.impl;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class ParamGetwayHandler extends GatewayHandle {
    @Override
    public void service() {
        System.out.println("param......");
        if(this.next != null){
            this.next.service();
        }
    }
}SessionGetwayHandler
package com.example.spring.boot.test.chainresponsibility.handle.impl;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class SessionGetwayHandler extends GatewayHandle {
    @Override
    public void service() {
        System.out.println("session......");
        if(this.next != null){
            this.next.service();
        }
    }
}通过枚举类来模拟数据库存储配置
创建网关实体类GatewayEntity
package com.example.spring.boot.test.chainresponsibility.entity;
import lombok.Data;
@Data
public class GatewayEntity {
    /**
     * 实体ID
     */
    private Integer id;
    /**
     * 描述
     */
    private String desc;
    /**
     * 组件类全限定名
     */
    private String handleClassName;
    /**
     * 上一个组件的ID
     */
    private Integer preId;
    /**
     * 下一个组件的ID
     */
    private Integer nextId;
    public GatewayEntity(Integer id, String desc, String handleClassName, Integer preId, Integer nextId) {
        this.id = id;
        this.desc = desc;
        this.handleClassName = handleClassName;
        this.preId = preId;
        this.nextId = nextId;
    }
}创建枚举类
package com.example.spring.boot.test.chainresponsibility.enums;
import com.example.spring.boot.test.chainresponsibility.entity.GatewayEntity;
public enum GatewayEnum {
    API_HANDLER(new GatewayEntity(1,"api接口限流","com.example.spring.boot.test.chainresponsibility.handle.impl.ApiLimitGatewayHandle",null,2)),
    BLACKLIST_HANDLER(new GatewayEntity(2,"黑名单拦截","com.example.spring.boot.test.chainresponsibility.handle.impl.BlacklistGetwayHandler",1,3)),
    SESSION_HANDLER(new GatewayEntity(3,"用户会话拦截","com.example.spring.boot.test.chainresponsibility.handle.impl.SessionGetwayHandler",2,4)),
    /**
     * 这是最后一个处理者,因此没有下一个 nexthandlerId 也就是它的 nexthandlerId = null
     */
    PARAM_HANDLER(new GatewayEntity(4,"参数过滤拦截","com.example.spring.boot.test.chainresponsibility.handle.impl.ParamGetwayHandler",3,null)),
    ;
    private GatewayEntity gatewayEntity;
    GatewayEnum(GatewayEntity entity){
        this.gatewayEntity = entity;
    }
    public GatewayEntity getGatewayEntity() {
        return gatewayEntity;
    }
}创建Dao和DaoImpl
package com.example.spring.boot.test.chainresponsibility.dao;
import com.example.spring.boot.test.chainresponsibility.entity.GatewayEntity;
public interface GatewayDao {
    /**
     * 通过ID获取网关实体
     * @param id 
     * @return
     */
    GatewayEntity getEntityById(Integer id);
    /**
     * 获取第一个网关实体类
     * @return 
     */
    GatewayEntity getFirstEntity();
}实现类
package com.example.spring.boot.test.chainresponsibility.dao.impl;
import com.example.spring.boot.test.chainresponsibility.dao.GatewayDao;
import com.example.spring.boot.test.chainresponsibility.entity.GatewayEntity;
import com.example.spring.boot.test.chainresponsibility.enums.GatewayEnum;
import java.util.HashMap;
import java.util.Map;
public class GatewayDaoImpl implements GatewayDao {
    private static Map<Integer, GatewayEntity> map = new HashMap<>();
    static{
        for(GatewayEnum gatewayEnum: GatewayEnum.values()){
            map.put(gatewayEnum.getGatewayEntity().getId(), gatewayEnum.getGatewayEntity());
        }
    }
    @Override
    public GatewayEntity getEntityById(Integer id) {
        if(id == null){
            return null;
        }
        return map.get(id);
    }
    @Override
    public GatewayEntity getFirstEntity() {
        for(GatewayEntity entity: map.values()){
            if(entity.getPreId() == null){
                return entity;
            }
        }
        return null;
    }
}创建Facatory构建责任链(将组建编排起来)采用了工厂模式
package com.example.spring.boot.test.chainresponsibility.factory;
import com.example.spring.boot.test.chainresponsibility.dao.GatewayDao;
import com.example.spring.boot.test.chainresponsibility.dao.impl.GatewayDaoImpl;
import com.example.spring.boot.test.chainresponsibility.entity.GatewayEntity;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class GatewayHandlerEnumFactory {
    private static GatewayDao gatewayDao = new GatewayDaoImpl();
    public static GatewayHandle buildGatewayHandler(){
        // 1. 获取第一处理者 那么那个是第一个处理者呢 preId == null 的就是第一个handler
        GatewayEntity firstEntity = gatewayDao.getFirstEntity();
        GatewayHandle firstGatewayHandler = newGatewayHandler(firstEntity);
        if(firstGatewayHandler == null){
            return null;
        }
        setNextGatewayHandler(firstEntity, firstGatewayHandler);
        return firstGatewayHandler;
    }
    private static void setNextGatewayHandler(GatewayEntity gatewayEntity,GatewayHandle gatewayHandle){
        if(gatewayHandle != null && gatewayEntity != null){
            Integer nextId = gatewayEntity.getNextId();
            GatewayEntity nextEntity = gatewayDao.getEntityById(nextId);
            GatewayHandle newGatewayHandler = newGatewayHandler(nextEntity);
            gatewayHandle.setNext(newGatewayHandler);
            //递归 设置
            setNextGatewayHandler(nextEntity, newGatewayHandler);
        }
    }
    /**
     * 反射实体化具体的处理者
     * @param gatewayEntity
     * @return
     */
    private static GatewayHandle newGatewayHandler(GatewayEntity gatewayEntity){
        if(gatewayEntity == null){
            return null;
        }
        String handlerClassName = gatewayEntity.getHandleClassName();
        try {
            Class<?> clazz = Class.forName(handlerClassName);
            return (GatewayHandle) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}测试
package com.example.spring.boot.test.chainresponsibility;
import com.example.spring.boot.test.chainresponsibility.factory.GatewayHandlerEnumFactory;
import com.example.spring.boot.test.chainresponsibility.handle.GatewayHandle;
public class GatewayClient {
    public static void main(String[] args) {
        GatewayHandle gatewayHandle = GatewayHandlerEnumFactory.buildGatewayHandler();
        gatewayHandle.service();
    }
}结果
api limit......
black list......
session......
param......