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

news/2024/9/24 6:33:53/

ruoyigateway_0">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(), "请求超过最大数,请稍候再试");}@Overridepublic 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;

	@Beanpublic RouterFunction routerFunction() {// 当接收到 /get的请求以及 ediaType.TEXT_PLAIN的时候就跑到handler里面去,也就是注入的获取验证码的handlerreturn RouterFunctions.route(RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),validateCodeHandler);}// handler里面调用创建验证码的方法@Componentpublic class ValidateCodeHandler implements HandlerFunction<ServerResponse> {@Autowiredprivate ValidateCodeService validateCodeService;@Overridepublic 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的东西的,具体还得研究一下。

	@Overridepublic 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.ppmy.cn/news/1529691.html

相关文章

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【Trace调测】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 Trace调测旨在帮助开发者获取内核的运行流程&#xff0c…

Highcharts甘特图基本用法(highcharts-gantt.js)

参考官方文档&#xff1a; https://www.highcharts.com/docs/gantt/getting-started-gantt https://www.highcharts.com/demo/gantt/project-management https://www.hcharts.cn/demo/gantt 链接在下面按需引入 https://code.highcharts.com/gantt/highcharts-gantt.js htt…

WebGL颜色与纹理

WEBGL中的着色器变量包括以下种类&#xff1a; 属性变量&#xff08;Attribute Variables&#xff09;&#xff1a;这些变量用于接收从应用程序中传递的顶点数据&#xff0c;比如顶点位置和颜色&#xff0c;是只读的不可修改。统一变量&#xff08;Uniform Variables&#xff…

PHP邮件发送教程:如何用PHP发送电子邮件?

php邮件怎么实现发送电子邮件&#xff1f;php怎么给邮箱发邮件&#xff1f; PHP作为一种广泛使用的服务器端脚本语言&#xff0c;提供了多种方法来实现电子邮件的发送。AokSend将详细介绍如何使用PHP邮件功能来发送电子邮件&#xff0c;帮助开发者轻松实现这一重要功能。 PHP…

思维链在论文写作中的应用:借助ChatGPT构建完整、清晰的论证

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 “思维链”&#xff08;Chain of Thought&#xff0c;CoT&#xff09;是一种通过逐步推理来解决复杂问题的方法&#xff0c;这种方法能够提高AI在某些任务上的表现。在论文写作中&#…

C++ | Leetcode C++题解之第432题全O(1)的数据结构

题目&#xff1a; 题解&#xff1a; class AllOne {list<pair<unordered_set<string>, int>> lst;unordered_map<string, list<pair<unordered_set<string>, int>>::iterator> nodes;public:AllOne() {}void inc(string key) {if (…

.NET 6.0 MVC使用Cookie进行身份验证

一般而言MVC 是不与其他系统发生数据交互&#xff0c;所以使用Cookie验证即可&#xff0c;无需安装拓展。 1.Program里面注册服务 //1.选择使用那种方式来身份验证 builder.Services.AddAuthentication(option > {option.DefaultAuthenticateScheme CookieAuthentication…

Protobuf:基本概念与使用流程

Protobuf&#xff1a;基本概念与使用流程 基本概念Linux 安装使用流程.proto文件编译使用 运行机制 基本概念 在进行网络编程时&#xff0c;经常需要进行数据传输&#xff0c;只有双方主机都保证数据格式的一致性&#xff0c;才能保证数据被正常解析。这个过程称为序列化与反序…