写点什么

如何给网关设计一款专属的权限控制「责任链设计模式」

  • 2021 年 11 月 11 日
  • 本文字数:3087 字

    阅读完需:约 10 分钟

}


}


@Component


@Slf4j


public class ConversationHandler extends GatewayHandler {


@Override


public void service() {


log.info("第三关 用户的会话信息拦截.......");


}


}


基于数据库实现



相关 SQL 语句


CREATE TABLE gateway_handler (


ID int(11) NOT NULL AUTO_INCREMENT COMMENT '主键 ID',


handler_name varchar(32) DEFAULT NULL COMMENT 'handler 名称',


handler_id varchar(32) DEFAULT NULL COMMENT 'handler 主键 id',


prev_handler_id varchar(32) DEFAULT NULL,


next_handler_id varchar(32) DEFAULT NULL COMMENT '下一个 handler',


PRIMARY KEY (ID)


) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COMMENT='权限表';




-- Records of gateway_handler




INSERT INTO gateway_handler VALUES ('16', 'Api 接口限流', 'currentLimitHandler', null, 'blacklistHandler');


INSERT INTO gateway_handler VALUES ('17', '黑名单拦截', 'blacklistHandler', 'currentLimitHandler', 'conversationHandler');


INSERT INTO gateway_handler VALUES ('18', '会话验证', 'conversationHandler', 'blacklistHandler', null);


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


Utils


=========


@Component


public class SpringUtils implements ApplicationContextAware {


private static ApplicationContext applicationContext;


@Override


public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {


this.applicationContext = applicationContext;


}


//获取 applicationContext


public static ApplicationContext getApplicationContext() {


return applicationContext;


}


//通过 name 获取 Bean.


public static Object getBean(String name){


return getApplicationContext().getBean(name);


}


//通过 class 获取 Bean.


public static <T> T getBean(Class<T> clazz){


return getApplicationContext().getBean(clazz);


}


//通过 name,以及 Clazz 返回指定的 Bean


public static <T> T getBean(String name,Class<T> clazz){


return getApplicationContext().getBean(name, clazz);


}


}


GatewayHandlerService


=========================


/**


  • @title: GatewayHandlerService


*/


@Service


public class GatewayHandlerService {


@Autowired


private GatewayHandlerMapper gatewayHandlerMapper;


private GatewayHandler firstGatewayHandler;


/**


  • 获取数据库第一个 handeler 封装


*/


public GatewayHandler getFirstGatewayHandler() {


if (firstGatewayHandler != null) {


return firstGatewayHandler;


}


//1.【第一个实体】


GatewayHandlerEntity firstGatewayHandlerEntity = gatewayHandlerMapper.getFirstGatewayHandler();


if(firstGatewayHandlerEntity==null){ return null; }


//2.【第一个 HandlerId】


String firstHhandlerId = firstGatewayHandlerEntity.getHandlerId();


//3.【第二个 HandlerId】


String secondHandlerId = firstGatewayHandlerEntity.getNextHandlerId();


//4.【第一个 bean 对象】


GatewayHandler firstGatewayHandler = SpringUtils.getBean(firstHhandlerId, GatewayHandler.class);


//5.【tmpHandler 为第一个 bean 对象】


GatewayHandler tmpHandler=firstGatewayHandler;


//如果下一个 HandlerId 不为 null,则继续


while (!StringUtils.isBlank(secondHandlerId)){


//6.【第二个 bean 对象】->11.【第三个 bean 对象】


GatewayHandler secondGatewayHandler = SpringUtils.getBean(secondHandlerId, GatewayHandler.class);


//7.【设置第一个 bean 对象的 next 为第二个 bean 对象】->12.【设置第二个 bean 对象的 next 为第三个 bean 对象】


tmpHandler.setNextGatewayHandler(secondGatewayHandler);


//8.【第二个实体】->13.【第三个实体】


GatewayHandlerEntity secondHandlerEntity = gatewayHandlerMapper.getByHandler(secondHandlerId);


if (secondHandlerEntity==null){ break; }


//9.【第三个 HandlerId】->14.【第四个 HandlerId】此时为 null,后面会退出循环


secondHandlerId=secondHandlerEntity.getNextHandlerId();


//10.【tmpHandler 为第二个 bean 对象】->15.【tmpHandler 为第三个 bean 对象】


tmpHandler=secondGatewayHandler;


}


//16.赋值


this.firstGatewayHandler=firstGatewayHandler;


//17.返回第一个 firstHandler 对象


return firstGatewayHandler;


}


}


数据库访问层


GatewayHandlerMapper


public interface GatewayHandlerMapper {


/**


  • 获取第一个 GatewayHandler


*/


@Select("SELECT handler_name AS handlerName,handler_id AS handlerid ,prev_handler_id AS prevhandlerid ,next_handler_id AS nexthandlerid FROM gateway_handler WHERE prev_handler_id is null;;")


public GatewayHandlerEntity getFirstGatewayHandler();


@Select("SELECT handler_name AS handlerName,handler_id AS handlerid ,prev_handler_id AS prevhandlerid ,next_handler_id AS nexthandlerid FROM gateway_handler WHERE handler_id=#{handlerId}")


public GatewayHandlerEntity getByHandler(String handlerId);


}


Entity 层


@Data


public class GatewayHandlerEntity implements Serializable, Cloneable {


/**


  • 主键 ID


*/


private Integer id;


/**


  • handler 名称


*/


private String handlerName;


/**


  • handler 主键 id


*/


private String handlerId;


/**


  • 下一个 handler


*/


private String nextHandlerId;


}


Controller 层


/**


  • @title: HandlerController


*/


@RestController


public class HandlerController {


@Autowired


private GatewayHandlerService gatewayHandlerService;


@RequestMapping("/client")


public String client() {


GatewayHandler firstGatewayHandler = gatewayHandlerService.getFirstGatewayHandler();


firstGatewayHandler.service();


return "success";


}


}


相关配置信息


==========


版权 @须臾之余


https://my.oschina.net/u/3995125


application.yml


###服务启动端口号


server:


port: 8080


spring:


datasource:


url: jdbc:mysql://127.0.0.1:3306/design_pattern?useUnicode=true&characterEncoding=UTF-8&useSSL=true


username: root


password: root


driver-class-name: com.mysql.jdbc.Driver


####打印 MyBatias 日志


logging:


level:

开发环境使用 DEBUG 生产环境 info 或者 error

com.xuyu.mapper: DEBUG


Maven 依赖信息


<parent>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-parent</artifactId>


<version>2.0.1.RELEASE</version>


</parent>


<dependencies>


<dependency>


<groupId>org.springframework.boot</groupId>


<artifactId>spring-boot-starter-web</artifactId>


</dependency>


<dependency>


<groupId>org.projectlombok</groupId>


<artifactId>lombok</artifactId>


<version>1.16.10</version>


</dependency>


<dependency>


<groupId>commons-lang</groupId>


<artifactId>commons-lang</artifactId>


<version>2.6</version>


</dependency>


<dependency>


<groupId>org.mybatis.spring.boot</groupId>


<artifactId>mybatis-spring-boot-starter</artifactId>


<version>1.1.1</version>


</dependency>


<dependency>


<groupId>mysql</groupId>


<artifactId>mysql-connector-java</artifactId>


</dependency>


</dependencies>


启动类


/**


  • @title: AppHandler


*/


@SpringBootApplication


@MapperScan("com.xuyu.mapper")


@EnableAutoConfiguration


public class AppHandler {


public static void main(String[] args) {


SpringApplication.run(AppHandler.class);

评论

发布
暂无评论
如何给网关设计一款专属的权限控制「责任链设计模式」