ruoyi源码解析学习 - 微服务版 - ruoyi-gateway

news2024/11/14 5:21:42

com.ruoyi.gateway

今天简单看看若依的gateway的配置模块干了啥

最近面试很多外包公司,都对低代码平台有点要求,这些代码虽说用起来不费劲,但是其中还是有很多细节能让我学习学习的。(微服务版,上次搞jeecgboot的笔试题差点把我人带走了)

在这里插入图片描述

简单的看一眼,总共分为4个文件夹和1个启动类。

0. pom文件

<parent>
   <groupId>com.ruoyi</groupId>
   <artifactId>ruoyi</artifactId>
   <version>3.6.4</version>
</parent>

dependencies
spring-cloud-starter-gateway
spring-cloud-starter-alibaba-nacos-discovery
spring-cloud-starter-alibaba-nacos-config
spring-cloud-starter-alibaba-sentinel
spring-cloud-alibaba-sentinel-gateway
sentinel-datasource-nacos
spring-boot-starter-actuator
spring-cloud-loadbalancer
kaptcha
ruoyi-common-redis
springdoc-openapi-webflux-ui

1. 先看一眼启动类

emm,没什么特别就加了一个注解,用来剔除数据库的自动配置的。

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })

2. 从头开始看,第一个是config

  • config
    • properties(首先也是一个目录,里面写了一些属性)
    • CaptchaConfig:验证码的配置
    • GatewayConfig:网关限流配置
    • KaptchaTextCreator:验证码文本生成器(这里是no usages的)
    • RouterFunctionConfiguration:路由配置
    • SpringDocConfig:文档的配置类

CaptchaConfig

这里用的是google的kaptcha的包,里面注册了两个bean,一个是default的验证码bean,一个是数字的bean。

GatewayConfig:这里主要是注册了一个自定义的限流处理

@Configuration
public class GatewayConfig{
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    // 这里的SentinelFallbackHandler自定义的限流处理,跳转过去看看
    public SentinelFallbackHandler sentinelGatewayExceptionHandler(){
        return new SentinelFallbackHandler();
    }
}

// 自定义限流异常处理
public class SentinelFallbackHandler implements WebExceptionHandler{
    private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange){
        return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试");
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex){
        if (exchange.getResponse().isCommitted()){
            return Mono.error(ex);
        }
        if (!BlockException.isBlockException(ex)){
            return Mono.error(ex);
        }
        return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
    }

    private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable){
        return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
    }
}

好像没啥特别,就是封装了一些自定义的返回,ServletUtils.webFluxResponseWriter这里也是一个返回的封装。

@Order(Ordered.HIGHEST_PRECEDENCE)

@Order用于指定Bean的加载顺序,注解的参数越小优先级越高,越会被优先加载。

public interface Ordered {
    int HIGHEST_PRECEDENCE = Integer.MIN_VALUE; 
    int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

    int getOrder();
}

KaptchaTextCreator 这个就不展开研究了,给我的话可能梭哈cv一下就完事了。

RouterFunctionConfiguration

这个配置类里面注入了handler的ValidateCodeService,这个类主要是用于获取验证码的
@Autowired
private ValidateCodeHandler validateCodeHandler;

	@Bean
    public RouterFunction routerFunction() {
    	// 当接收到 /get的请求以及 ediaType.TEXT_PLAIN的时候就跑到handler里面去,也就是注入的获取验证码的handler
        return RouterFunctions.route(
                RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
                validateCodeHandler);
    }

	// handler里面调用创建验证码的方法
	@Component
	public class ValidateCodeHandler implements HandlerFunction<ServerResponse> {
	    @Autowired
	    private ValidateCodeService validateCodeService;
	
	    @Override
	    public Mono<ServerResponse> handle(ServerRequest serverRequest) {
	        AjaxResult ajax;
	        try {
	            ajax = validateCodeService.createCaptcha();
	        } catch (CaptchaException | IOException e) {
	            return Mono.error(e);
	        }
	        return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax));
	    }
	}

也是注册了一个bean,返回了.route这个方法,也跳转进去看看干嘛的。

/**
	 * Route to the given handler function if the given request predicate applies.
	 * <p>For instance, the following example routes GET requests for "/user" to the
	 * {@code listUsers} method in {@code userController}:
	 * <pre class="code">
	 * RouterFunction&lt;ServerResponse&gt; route =
	 *     RouterFunctions.route(RequestPredicates.GET("/user"), userController::listUsers);
	 * </pre>
	 * @param predicate the predicate to test
	 * @param handlerFunction the handler function to route to if the predicate applies
	 * @param <T> the type of response returned by the handler function
	 * @return a router function that routes to {@code handlerFunction} if
	 * {@code predicate} evaluates to {@code true}
	 * @see RequestPredicates
	 */
	public static <T extends ServerResponse> RouterFunction<T> route(
			RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
		// 这里就类似对断言进行了配置
		return new DefaultRouterFunction<>(predicate, handlerFunction);
	}

SpringDocConfig

这里做的是swagger的配置,多看了一眼这个订阅类型方法,好像是返回一些nacos的东西的,具体还得研究一下。

	@Override
    public Class<? extends Event> subscribeType() {
        return InstancesChangeEvent.class;
    }

3. filter

AuthFilter:网关鉴权

	// 实现两个类
	public class AuthFilter implements GlobalFilter, Ordered

嗯?这个实现Ordered的类居然还能这样用,属实是我太菜了,这样就又能自己定义优先级了
@Override
public int getOrder() {
return -200;
}

其余的就是一些基本的鉴权验证了,判断令牌的状态等等等等

BlackListUrlFilter:黑名单过滤器

extends AbstractGatewayFilterFactory<>,网关的filter factory。

重写了GatewayFilterFactory里面的apply,然后判断是否为黑名单然后返回一个封装好的数据。(一个类套一个好家伙,倒也不复杂,果然写得好看的代码就是绕)

CacheRequestFilter:获取body的请求数据

这个又是个什么玩意?解决流不能重复读取的问题?也跟黑名单过滤器一样继承了相同的一个东西,然后在泛型里自己定义一个内部类来搞。

ValidateCodeFilter:验证码过滤器

跟上面也是同样的,what?AbstractGatewayFilterFactory这个东西有点牛的。

XssFilter:跨站脚本过滤器

implements GlobalFilter, Ordered

同样是实现了ordered,并且这次也实现了GlobalFilter这个东西,重写filter方法,主要是用来过滤请求的。这些类可以拿过来就用了。

4. handler

这里面的类都会在上面的类中被调用而抽出来放的。

  • 网关统一处理的异常
  • 自定义限流异常处理
  • 验证码的获取(这个在service中也抽出来了)

差不多就这样,得看看这个AbstractGatewayFilterFactory<>是个什么来头

在这里插入图片描述

看这个类的写法,跟若以这里抽出来的写的确实是类似的,但是apply方法不是放在这里的,还在上一级的GatewayFilterFactory中,确实里面都会搭配上一个内部类来使用。

在这里插入图片描述

这里就是上一级的GatewayFilterFactory

在这里插入图片描述

原来每一次都需要定义一个内部类是因为这里是一个class,所以为了方便直接就丢里面。

#学习完毕,done

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2159739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R包安装教程,如何安装rjags和infercnv

一.介绍 在数据分析过程中&#xff0c;R语言因其强大的统计分析能力和丰富的包生态系统&#xff0c;成为众多研究人员和数据科学家的首选工具。本文将详细介绍如何在R环境中安装两个重要的R包——rjags和infercnv。rjags用于与JAGS&#xff08;Just Another Gibbs Sampler&…

热斑黄斑光伏发电板 红外黄斑检测图像数据集内含最高温度信息 1200张,jpg格式。

热斑黄斑光伏发电板 红外黄斑检测图像数据集 内含最高温度信息 1200张&#xff0c;jpg格式。 热斑黄斑光伏发电板红外黄斑检测图像数据集介绍 数据集名称 热斑黄斑光伏发电板红外黄斑检测图像数据集&#xff08;Hot Spot and Yellow Spot Detection in Photovoltaic Panels I…

Linux下进程通信与FIFO操作详解

Linux下进程通信与FIFO操作详解 一、命名管道(FIFO)概述1.1 命名管道的特点1.2 创建命名管道二、命名管道的操作2.1 打开命名管道2.2 读写命名管道2.3 关闭命名管道三、命名管道的使用实例3.1 命名管道的创建和通信过程3.1.1 发送方(writer)3.1.2 接收方(reader)3.2 运行…

java项目之健身房管理系统源码(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的健身房管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 健身房管理系统的主要使用…

Java框架学习(Spring)(tx)(03)

简介&#xff1a;以本片记录在尚硅谷学习ssm-spring-tx时遇到的小知识 详情移步&#xff1a;想参考的朋友建议全部打开相互配合学习&#xff01; 视频&#xff1a; 057-spring-tx-编程式和声明式事务理解_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AP411s7D7?p5…

第九节 Opencv自带颜色表操作

知识点&#xff1a;Look Up lTable&#xff08;LUT&#xff09;查找表 了解LUT查找表的作用与用法&#xff0c;代码实现与API介绍 -applyColorMap&#xff08;src,dst,COLORMAP&#xff09; -src表示输入图像 -dst表示输出图像 匹配到的颜色LUT&#xff0c;Opencv支持13种…

Android OpenGLES2.0开发(一):艰难的开始

生而为人&#xff0c;本质上&#xff0c;都是孤独的&#xff01; 引言 我一直觉得OpenGL ES是一块硬骨头&#xff0c;每次用到GLSurfaceView作为Camera的预览视图时&#xff0c;总是去网上找现成的代码。CtrlC和CtrlV之后总有一种沾沾自喜的感觉&#xff0c;但是你要让我改里面…

JavaScript --- 字符串常用方法(1)

chartAt(索引)&#xff0c;返回索引对应字符 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" …

Java | Leetcode Java题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; class Solution {public int minMutation(String start, String end, String[] bank) {int m start.length();int n bank.length;List<Integer>[] adj new List[n];for (int i 0; i < n; i) {adj[i] new ArrayList<Intege…

chsharp文件如何查找在unity中使用的 位置?

在 Unity 中&#xff0c;C 脚本文件&#xff08;.cs 文件&#xff09;被用于控制游戏对象的行为。要查找某个 C 文件在 Unity 项目中被使用的位置&#xff0c;你可以通过以下几种方法&#xff1a; 1. 查找依赖项&#xff08;References&#xff09; Unity 提供了一个工具&#…

物联网助力智慧交通:优势与前景

智慧交通是当今城市发展的必然趋势&#xff0c;而物联网技术在交通运输领域的应用正是为实现智慧交通建设提供了前所未有的机遇和优势。物联网作为连接和控制物理世界的重要技术手段&#xff0c;在交通领域的应用极大地改善了交通系统的效率、安全性和环保性。 首先&#xff0c…

LabVIEW软件出现Bug如何解决

在LabVIEW开发中&#xff0c;程序出现bug是不可避免的。无论是小型项目还是复杂系统&#xff0c;调试与修复bug都是开发过程中的重要环节。下文介绍如何有效解决LabVIEW软件中的bug&#xff0c;包括常见错误类型、调试工具、错误处理机制。 1. 常见Bug类型分析 在LabVIEW中&am…

使用vite+react+ts+Ant Design开发后台管理项目(二)

前言 本文将引导开发者从零基础开始&#xff0c;运用、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈&#xff0c;构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导&#xff0c;文章旨在为开发者揭示如何利用这些技术工具…

C语言 | Leetcode C语言题解之第429题N叉树的层序遍历

题目&#xff1a; 题解&#xff1a; #define MAX_LEVE_SIZE 1000 #define MAX_NODE_SIZE 10000int** levelOrder(struct Node* root, int* returnSize, int** returnColumnSizes) {int ** ans (int **)malloc(sizeof(int *) * MAX_LEVE_SIZE);*returnColumnSizes (int *)mal…

如何利用 opencv 进行 ROI(感兴趣)获取和实现 VR(虚拟现实) 演播室的播放

我是从事医疗软件的开发的。 经常需要从拍摄的医疗视频中获取出病理区域。并计算病理区域的周长和面积。 用 opencv 的术语,这就是感兴趣区域的获取。 (因为都是实时视频,所以速度很关键。代码效率很重要) 有时,需要标注出病理区域,并将非病理区域从视频中去除掉。 如果将…

云栖大会上我遇见了站长转型自媒体最成功的人

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 非常荣幸参加了第十六届2024云栖大会。文章很短&#xff0c;但很精。 这次大会有3大特点&#xff1a;人巨多、热、信号差&#xff0c;而且云栖大会上我遇见了站长转型自媒体最成功的人。甚至还有人说&#xff1a;云…

光子架与电子架 -- 光子架与电子架

电子架 指插放交叉板、OTU单板、支/线路板、保护类单板的子架。 在通用型平台子架和平台子架中如果仅插放OTU单板&#xff08;非中继模式&#xff09;视为电子架。光电混合的子架视为电子架。 电子架主要实现将客户侧信号转换成标准波长的光信号&#xff0c;供光子架调度。 光子…

免费的高质量、美观的甘特图模板

呈现您的项目规划新高度&#xff0c;精选几款高品质、视觉出众的甘特图模板。 甘特图Excel模板-Ganttable系统风格甘特图Excel模板-专业甘特图Excel模板-浅蓝色甘特图Excel模板-深灰色 这些 Excel 甘特图模板均源自 Ganttable 甘特图AI工具的智能生成与导出。利用 Ganttable&a…

ARM单片机的中断详细过程(重要)

ARM单片机的中断详细过程&#xff08;重要&#xff09; 一、ARM异常中断 ARM的异常&#xff08;中断源&#xff09;总共分为三类&#xff08;八种&#xff09;&#xff1a; 三类&#xff1a; &#xff08;1&#xff09;执行指令引起的直接异常&#xff1a;软件中断&#xff…

Golang | Leetcode Golang题解之第433题最小基因变化

题目&#xff1a; 题解&#xff1a; func diffOne(s, t string) (diff bool) {for i : range s {if s[i] ! t[i] {if diff {return false}diff true}}return }func minMutation(start, end string, bank []string) int {if start end {return 0}m : len(bank)adj : make([][…