草庐IT

若依框架(ruoyi-cloud)学习

蛋头弹头 2025-06-14 原文

com.ruoyi     
├── ruoyi-ui              // 前端框架 [80]
├── ruoyi-gateway         // 网关模块 [8080]
├── ruoyi-auth            // 认证中心 [9200]
├── ruoyi-api             // 接口模块
│       └── ruoyi-api-system                          // 系统接口
├── ruoyi-common          // 通用模块
│       └── ruoyi-common-core                         // 核心模块
│       └── ruoyi-common-datascope                    // 权限范围
│       └── ruoyi-common-datasource                   // 多数据源
│       └── ruoyi-common-log                          // 日志记录
│       └── ruoyi-common-redis                        // 缓存服务
│       └── ruoyi-common-seata                        // 分布式事务
│       └── ruoyi-common-security                     // 安全模块
│       └── ruoyi-common-swagger                      // 系统接口
├── ruoyi-modules         // 业务模块
│       └── ruoyi-system                              // 系统模块 [9201]
│       └── ruoyi-gen                                 // 代码生成 [9202]
│       └── ruoyi-job                                 // 定时任务 [9203]
│       └── ruoyi-file                                // 文件服务 [9300]
├── ruoyi-visual          // 图形化管理模块
│       └── ruoyi-visual-monitor                      // 监控中心 [9100]
├──pom.xml                // 公共依赖

ruoyi-api

└── ruoyi-api-system

里面存放的系统内各个模块都会用到的东西。比如用户信息、用户角色、部门信息

ruoyi-auth

认证中心
登录、注册等相关的控制器

ruoyi-common

ruoyi-common通用模块

└── ruoyi-common-log

日志记录
@Log 注解的相关操作

注:框架里的各种自定义的注解的功能,都在对应的模块里用AOP横切进来的。

└── ruoyi-common-security

└──aspect

└──PreAuthorizeAspect

注解鉴权
鉴权不通过直接报错

└──auth

└──authUtil

用户权限工具类
但是这个类只像是一个接口,具体的实现都在authLogic里面

└──authLogic

用户权限工具类的具体实现逻辑

ruoyi-gateway

└── filter

└──AuthFilter

全局过滤器
每个请求进来都会先进入过滤器,鉴权

└── service

└──ValidateCodeService

验证码处理
配置信息在nacos中的gateway配置文件中。(可配置验证码类型:计算 or 字符)

ruoyi-modules

└── ruoyi-system

└── SysMenuController

菜单管理相关控制器(操作菜单信息)
刚进入系统时获取菜单路由也在这

└── SysRoleController

角色管理相关控制器(操作角色信息)

└── SysUserController

用户管理相关控制器(操作用户信息)

问题记录

请求执行顺序

  1. 因为前端是发送请求到网关。所以请求会先到网关的全局过滤器,并将用户信息设置到请求头

    com.ruoyi.gateway.filter.AuthFilter

  2. 通过网关的过滤器后,会进入拦截器

    com.ruoyi.common.security.config.WebMvcConfig

  3. 被拦截的请求,会进入自定义的请求头拦截器,从请求头中获取用户信息存到线程中

    com.ruoyi.common.security.interceptor.HeaderInterceptor

  4. 进入controller中

  5. controller执行结束后会删除当前线程。

未登录拦截

在未登录的情况下,直接访问 http://localhost:81/index ,不会进入首页,而是被弹到登录页。

  1. 首先会在前端做验证,从Cookie中获取token,判断是否有token,没有则直接弹到登录页:

  1. 若通过前端的话,请求到达后端,会进入网关的全局过滤器,判断token的有效性,无效就弹回:

发现一个bug,如果手动修改了浏览器Cookie中的token,会导致后端token解析报错,导致所有页面都无法访问,包括登录页面。必须要手动把token删除,才能正常访问。

每个请求进来都会先进入过滤器,鉴权

权限注解

若依框架中自定义了三个权限注解

  • @RequiresLogin登录认证:只有登录之后才能进入该方法。
  • @RequiresPermissions权限认证:必须具有指定权限才能进入该方法。
  • @RequiresRoles角色认证:必须具有指定角色标识才能进入该方法

这三个注解的具体实现是通过AOP横切来实现的:PreAuthorizeAspect

  1. 定义三个注解为切入点

  1. @Pointcut@Around联合注解

  1. 对被代理的Method对象进行注解检查

访问每个菜单都是有权限要求的。

数据范围注解

框架中自定义了1个数据范围注解:@DataScope

这个注解可以传3个参数,不过一般只用2个。

由于系统中数据众多,角色众多,总不可能让普通员工也能看到所有员工的信息吧,所以需要为每种角色分配数据权限范围。比如:董事长可以看所有员工数据,部门主管可以看部门和子部门里所有员工的数据,普通员工只能看本部门员工信息。

若依把这个功能用注解封装了起来。

数据库中的sys_role表中存储了角色的数据范围data_scope字段:

数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)新增角色时默认为’1’

展示数据但是需要判断数据范围的方法,只需要在service实现类上增加@DataScope注解,并告知sql语句中的部门表的别名或者用户表的别名,注解的切面类会根据数据表中data_scope字段来为sql语句中拼接相应的sql语句(因为sql语句中有多表连接,所以需要传别名),并把需要拼接的sql语句放到point(被代理的方法)的参数对象里,让mapper.xml可以读取到需要拼接的sql。

当前框架中需要用到数据范围注解的:

  1. 根据条件分页查询角色数据:只能获取范围内的角色列表。比如,当前员工只能看到本部门里有哪些角色。
  2. 查询部门管理数据:只能获取数据范围内的部门列表。比如,当前员工可以看到本部门和本部门和子部门列表。
  3. 根据条件分页查询用户列表:只能获取范围内的用户列表。比如,当前员工只能看到本部门的用户列表。
  4. 根据条件分页查询已分配用户角色列表:只能获取范围内的角色的已分配用户列表,比如,当前员工只能获取本部门内已分配该角色的用户列表。
  5. 根据条件分页查询未分配用户角色列表:获取范围内的未分配该角色的用户列表,比如,当前员工只能获取本部门内未分配该角色的用户列表。

获取当前用户信息

若依框架中获取当前操作用户信息是从当前线程中获取的,当前线程中存放了用户信息。
这里有一个关键的东西:TransmittableThreadLocal,这个是alibaba提供的一个工具包中的类,主要作用就是解决线程池场景下的变量传递问题。这里会存储当前用户的信息。

package com.ruoyi.common.core.context;

/**
 * 获取当前线程变量中的 用户id、用户名称、Token等信息 
 * 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取
 *
 * @author ruoyi
 */
public class SecurityContextHolder{
    private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();

    ...
}
  1. 每个外部请求进来都会先到网关的过滤器中,过滤器跳过不需要验证的路径后,就会获取请求里的token,并解析token得到用户信息,把信息塞到请求头中,把信息传递到拦截器中。

  1. tomcat会为每一个请求分配一个线程,拦截器里的自定义请求头拦截器就会把请求头中的信息存到当前线程当中


  1. 这样的话,当前线程在进入Controller前就已经携带了用户的相关信息了,所以可以直接在代码中获取用户信息。

map中的数据get()后不会被删除。get()后会删除的是python里面的queue。差点混乱了。

  1. 方法成功执行结束后,会删除当前线程。


代码问题

循环查库

如果有很多的角色,就循环查库了


⭐注意⭐

对象赋值

一个对象直接赋给另一个新的对象,这种赋值只是地址赋值,两个对象指向同一个地址,只要其中任何一个改变相应的值,两个都会一起变化。并不是数据拷贝。

BeanUtils.copyProperties();是数据拷贝。

User user = new User(1, "zhangSan", 25, student);
User newUser=user;

修改形参

Java在调用方法时,在方法内部修改形参会不会影响到实参:

  • 如果是基本类型,则实参不会变(传的是值)
  • 如果是对象,则实参会改变(传的是引用)

八股文都差点忘了

有关若依框架(ruoyi-cloud)学习的更多相关文章

  1. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  2. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  3. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  4. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  5. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  6. ruby - sinatra 框架的 MVC 模式 - 2

    我想开始使用“Sinatra”框架进行编码,但我找不到该框架的“MVC”模式。是“MVC-Sinatra”模式或框架吗? 最佳答案 您可能想查看Padrino这是一个围绕Sinatra构建的框架,可为您的项目提供更“类似Rails”的感觉,但没有那么多隐藏的魔法。这是使用Sinatra可以做什么的一个很好的例子。虽然如果您需要开始使用这很好,但我个人建议您将它用作学习工具,以对您来说最有意义的方式使用Sinatra构建您自己的应用程序。写一些测试/期望,写一些代码,通过测试-重复:)至于ORM,你还应该结帐Sequel其中(imho

  7. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

  8. 深度学习12. CNN经典网络 VGG16 - 2

    深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG

  9. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  10. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

随机推荐