若依开源框架解析

时间:2025-03-18 08:47:20

pojo层:全称为(Plain Ordinary Java Object 普通Java对象) 存放普通的JavaBean类

Model层:它的JavaBean类,封装的是前端在数据库中需要使用的数据。

知识点2:

若依的前后端未分离版本和vue版本都是基于SpringBoot开发的轻量级Java快速开发框架,他们分模块开发,在我理解其实也是把其他的模块引入主模块使用,保证大家可以分模块开发。和引入jar包是一样的。

知识点3:

若依的@excel注解是为了实现导出excel表。

知识点4:

若依cloud中各个微服务的作用:

     
├── ruoyi-ui              // 前端框架 [80]
├── ruoyi-gateway         // 网关模块 [8080]
├── ruoyi-auth            // 认证中心 [9200]           // 独立的认认证授权中心,有启动类
├── ruoyi-api             // 接口模块
│       └── ruoyi-api-system                          // 系统接口   系统抽取的统一的接口api,没有启动类
├── ruoyi-common                                      // 抽离的通用模块工具,没有启动类
│       └── ruoyi-common-core                         // 核心模块
│       └── ruoyi-common-datascope                    // 权限范围
│       └── ruoyi-common-datasource                   // 多数据源
│       └── ruoyi-common-log                          // 日志记录
│       └── ruoyi-common-redis                        // 缓存服务
│       └── 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]
├──                // 公共依赖

知识点5:用到了匿名内部类写法

/**
 * 文件服务降级处理
 * 
 * @author ruoyi
 */
@Component
public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
{
    private static final Logger log = ();

    @Override
    public RemoteFileService create(Throwable throwable)
    {
        ("文件服务调用失败:{}", ());
        return new RemoteFileService()
        {
            @Override
            public R<SysFile> upload(MultipartFile file)
            {
                return ("上传文件失败:" + ());
            }
        };
    }
}

知识点6:微服务若依环境搭建(重点)

若依微服务版手把手教你本地搭建环境并运行前后端项目 - 霸道流氓 - 博客园

知识点7:是nacos的初始化数据库,ry-cloud是业务库,ry-config是若依的nacos库。ry_20200924.sql和是ry-cloud的sql,ry_config_20200924.sql是ry-config的sql

知识点7:若依aop理解,冰山一角

深入分析若依数据权限@datascope (注解+AOP+动态sql拼接) 【循序渐进,附分析过程】_金发罗婕的博客-****博客_若依数据权限

若依框架数据权限源码解析-****博客

知识点8:若依异常理解,见自定义异常和全局异常处理类博客

知识点9:为什么接口返回类型有的用R 有的用AjaxResult?

序列化方式不同,AjaxResult继承了HashMap HashMap虽然也实现了Serializable但是有些秘密在里面 有兴趣可以了解下,也可以去了解下 不同序列化 方式的利弊~

知识点9:若依通过自定义注解@innerAuth+AOP来拒绝外部请求

若依框架解读(微服务版)——2.模块间的调用逻辑(ruoyi-api模块)(OpenFeign)_初见qwer的博客-****博客_若依微服务框架原理

知识点10:(重点)若依权限注解:注解类RequiresLogin、RequiresPermissions、RequiresRoles,分别用于登录认证、权限认证和角色认证
切面类PreAuthorizeAspect,基于 Spring Aop 的注解鉴权
被代理类SysJobController,被代理类就是添加注解的方法所在的类,可以是任意一个类

若依权限校验源码分析_紫荆之后-的博客-****博客_若依权限验证

知识点11:若依拦截器过滤器使用

若依登陆过程及过滤器拦截器的使用:

用户登陆接口:1、把用户信息通过uuid即token作为key,存储在缓存中,并设置过期时间,2、通过jwt存储token,userId,userName在map中,设置过期时间,通过jwt创建一个编码后的access_token和expireTime,并返回token在前端

过滤器:用户前端传递的access_token通过Jwt解析,尝试获取userkey(即token),userid,username

并判断是否过期,为空等。如果异常即刻报错,否则将解析的userkey,userid,username纳入请求头中,请求接着交给拦截器

拦截器:拦截器从请求头中获取userkey,userid,username,通过userkey从缓存中获取用户信息,并刷新缓存中用户信息的过期时间。并将用户信息加入到本地的TransmittableThreadLocal<Map<String, Object>>中,方便用户获取当前用户信息。

知识点12:幂等性 _ 防重复提交(若依前后端分离版中的代码)

幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次。 调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。

比如下面这些情况,如果没有实现接口幂等性会有很严重的后果: 支付接口,重复支付会导致多次扣钱 ;订单接口,同一个订单可能会多次创建。
 

gitee:RuoYi-Vue: ???? 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本

使用拦截器实现,在接口方法上添加@RepeatSubmit注解,注解参数说明:

参数 类型 默认值 描述
interval int 5000 间隔时间(ms),小于此时间视为重复提交
message String 不允许重复提交,请稍后再试 提示消息

使用redis缓存接口的请求URL及参数信息,如果存在且一致并在额定时间范围内,不让重复提交。

package ;

import ;
import ;
import ;
import ;
import ;
import ;

/**
 * 自定义注解防止表单重复提交
 * 
 * @author ruoyi
 *
 */
@Inherited
@Target()
@Retention()
@Documented
public @interface RepeatSubmit
{
    /**
     * 间隔时间(ms),小于此时间视为重复提交
     */
    public int interval() default 5000;

    /**
     * 提示消息
     */
    public String message() default "不允许重复提交,请稍候再试";
}
package ;

import ;
import ;
import ;

import ;
import ;
import ;
import ;
import .;
import ;
import ;

/**
 * 防止重复提交拦截器
 *
 * @author ruoyi
 */
@Component
public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        if (handler instanceof HandlerMethod)
        {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = ();
            RepeatSubmit annotation = ();
            if (annotation != null)
            {
                if ((request, annotation))
                {
                    AjaxResult ajaxResult = (());
                    (response, (ajaxResult));
                    return false;
                }
            }
            return true;
        }
        else
        {
            return true;
        }
    }

    /**
     * 验证是否重复提交由子类实现具体的防重复提交的规则
     *
     * @param request
     * @return
     * @throws Exception
     */
    public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
}