设计模式-责任链模式
通过模式数据库来配置责任链顺序,运用案例,网关需要过滤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......
|