RuoYi 框架中核心的 `PermitAllUrlProperties` 配置类

你提供的这段代码是 RuoYi 框架中核心的PermitAllUrlProperties配置类,其核心作用是自动扫描项目中所有标注了@Anonymous注解的 Controller 类/方法,提取对应的 URL 路径并统一管理,最终为 Sa-Token 等权限拦截器提供“允许匿名访问”的 URL 列表。

一、代码整体功能总结

这个类实现了InitializingBeanApplicationContextAware接口,核心逻辑是:

  1. 在 Spring 容器初始化完成后,扫描所有@RequestMapping注解的 Controller 方法;
  2. 识别标注了@Anonymous注解的类/方法,提取其 URL 路径;
  3. 将 URL 中的路径变量(如{id})替换为通配符*,最终汇总成一个“匿名访问 URL 列表”;
  4. 对外提供getUrls()方法,供 Sa-Token 拦截器等组件获取这些免登录的 URL。

二、代码逐模块详细解释

1. 类注解与核心成员
@Configuration// 声明为Spring配置类,纳入容器管理publicclassPermitAllUrlPropertiesimplementsInitializingBean,ApplicationContextAware{// 正则表达式:匹配URL中的路径变量(如 {id}、{userId})privatestaticfinalPatternPATTERN=Pattern.compile("\\{(.*?)\\}");// Spring应用上下文,用于获取容器中的BeanprivateApplicationContextapplicationContext;// 存储所有允许匿名访问的URL列表privateList<String>urls=newArrayList<>();// 通配符常量,用于替换路径变量publicStringASTERISK="*";}
  • InitializingBean:实现该接口的afterPropertiesSet()方法,会在 Spring 容器初始化完当前 Bean 的属性后执行;
  • ApplicationContextAware:实现该接口的setApplicationContext()方法,可获取 Spring 应用上下文(用于获取RequestMappingHandlerMapping);
  • PATTERN:正则匹配{xxx}格式的路径变量,比如将/system/user/{id}中的{id}匹配出来。
2. 核心方法:setApplicationContext(获取Spring上下文)
@OverridepublicvoidsetApplicationContext(ApplicationContextcontext)throwsBeansException{this.applicationContext=context;}
  • 作用:Spring 容器初始化时,自动将应用上下文注入到当前类的applicationContext成员变量中;
  • 后续可通过该上下文获取RequestMappingHandlerMapping(SpringMVC 中管理所有请求映射的核心 Bean)。
3. 核心方法:afterPropertiesSet(扫描并提取匿名URL)

这是整个类的核心逻辑,Spring 容器初始化完成后自动执行:

@OverridepublicvoidafterPropertiesSet(){// 1. 获取SpringMVC中管理所有@RequestMapping映射的核心BeanRequestMappingHandlerMappingmapping=applicationContext.getBean(RequestMappingHandlerMapping.class);// 2. 获取所有请求映射:key=RequestMappingInfo(URL、请求方式等),value=HandlerMethod(对应Controller方法)Map<RequestMappingInfo,HandlerMethod>map=mapping.getHandlerMethods();// 3. 遍历所有请求映射map.keySet().forEach(info->{HandlerMethodhandlerMethod=map.get(info);// 4. 第一步:扫描方法上的@Anonymous注解Anonymousmethod=AnnotationUtils.findAnnotation(handlerMethod.getMethod(),Anonymous.class);// 如果方法上有@Anonymous注解,提取URL并处理Optional.ofNullable(method).ifPresent(anonymous->Objects.requireNonNull(info.getPatternsCondition().getPatterns()).forEach(url->{// 替换URL中的路径变量(如{id})为*,加入列表urls.add(RegExUtils.replaceAll(url,PATTERN,ASTERISK));}));// 5. 第二步:扫描类上的@Anonymous注解(Controller类)Anonymouscontroller=AnnotationUtils.findAnnotation(handlerMethod.getBeanType(),Anonymous.class);// 如果类上有@Anonymous注解,提取URL并处理Optional.ofNullable(controller).ifPresent(anonymous->Objects.requireNonNull(info.getPatternsCondition().getPatterns()).forEach(url->{urls.add(RegExUtils.replaceAll(url,PATTERN,ASTERISK));}));});}

关键逻辑拆解:

  • 步骤1-2:获取RequestMappingHandlerMapping并拿到所有@RequestMapping映射关系,这是 SpringMVC 内部存储所有接口 URL 的核心数据结构;
  • 步骤4:检查 Controller 方法上是否有@Anonymous注解:
    • 比如@GetMapping("/user/{id}")+@Anonymous的方法,会被识别;
    • info.getPatternsCondition().getPatterns():获取该方法对应的所有 URL 路径(如[/user/{id}]);
    • RegExUtils.replaceAll(url, PATTERN, ASTERISK):将{id}替换为*,最终 URL 变为/user/*
  • 步骤5:检查 Controller 类上是否有@Anonymous注解(优先级低于方法注解):
    • 比如@RestController @Anonymous @RequestMapping("/system/dept")的类,其下所有方法的 URL 都会被加入匿名列表;
  • Optional.ofNullable(…):避免空指针,仅当注解存在时才执行后续逻辑。
4. Getter/Setter 方法
publicList<String>getUrls(){returnurls;}publicvoidsetUrls(List<String>urls){this.urls=urls;}
  • 作用:对外提供获取“匿名URL列表”的入口,你之前的SaTokenConfigAllUrlHandler大概率会调用这个getUrls()方法,获取所有允许匿名访问的 URL。

三、使用场景与示例

1. @Anonymous 注解的使用示例
// 示例1:Controller类上标注@Anonymous,该类下所有方法都允许匿名访问@Anonymous@RestController@RequestMapping("/system/login")publicclassLoginController{@PostMapping("/doLogin")publicAjaxResultdoLogin(){/* 登录逻辑 */}}// 示例2:单个方法上标注@Anonymous,仅该方法允许匿名访问@RestController@RequestMapping("/system/user")publicclassUserController{@Anonymous@GetMapping("/{id}")publicAjaxResultgetUserById(@PathVariableLongid){/* 查询用户逻辑 */}}
2. URL 处理结果示例
原始URL处理后URL(加入urls列表)说明
/system/login/doLogin/system/login/doLogin无路径变量,直接保留
/system/user/{id}/system/user/*路径变量{id}替换为*
/order/{orderId}/detail/{itemId}/order/*/detail/*多个路径变量全部替换

四、与 SaTokenConfig 的关联

你之前的SaTokenConfig中用到了AllUrlHandler.getUrls(),而AllUrlHandler底层大概率会整合:

  1. PermitAllUrlProperties.getUrls()@Anonymous注解的URL);
  2. SecurityProperties.getExcludes()(配置文件中手动排除的URL);
    最终为 Sa-Token 拦截器提供完整的“免登录URL列表”,确保这些URL不会被StpUtil.checkLogin()拦截。

五、核心设计亮点

  1. 自动扫描:无需手动配置匿名URL,只需在类/方法上标注@Anonymous,自动识别并加入列表;
  2. 路径变量兼容:将{id}替换为*,避免因路径变量导致的URL匹配失败(如/user/123能匹配/user/*);
  3. Spring 生命周期整合:利用InitializingBeanApplicationContextAware,在容器初始化阶段完成扫描,保证数据提前加载。

总结

  1. PermitAllUrlProperties是 RuoYi 框架中自动收集@Anonymous注解URL的核心配置类,通过扫描 SpringMVC 的请求映射,提取并处理匿名访问的URL;
  2. 核心逻辑是将URL中的路径变量({xxx})替换为通配符*,确保权限拦截器能正确匹配;
  3. 该类的getUrls()方法为 Sa-Token 拦截器提供“匿名URL列表”,是框架免登录URL管理的关键组件。

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

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

相关文章

JMeter效率提升:5个90%开发者不知道的技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个JMeter效率工具包&#xff0c;包含&#xff1a;1. 智能脚本录制器&#xff0c;自动去除冗余请求&#xff1b;2. 参数化数据生成器&#xff0c;支持多种数据格式&#xff1…

RaNER模型部署指南:中文命名实体识别WebUI搭建步骤详解

RaNER模型部署指南&#xff1a;中文命名实体识别WebUI搭建步骤详解 1. 引言 1.1 AI 智能实体侦测服务 在信息爆炸的时代&#xff0c;非结构化文本数据&#xff08;如新闻、社交媒体内容、文档资料&#xff09;占据了企业与研究机构数据总量的80%以上。如何从中高效提取关键信…

传统下载 vs AI获取原创力文档:效率对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个对比工具&#xff0c;模拟传统手动下载和AI自动获取原创力文档的全过程&#xff0c;记录时间、成功率和用户体验等指标。生成可视化报表&#xff0c;突出AI方法的效率优势…

Qwen2.5-7B模型轻量化:云端GPU 1小时量化,体积缩小4倍

Qwen2.5-7B模型轻量化&#xff1a;云端GPU 1小时量化&#xff0c;体积缩小4倍 1. 为什么需要模型轻量化&#xff1f; 作为移动端开发者&#xff0c;你可能经常遇到这样的困境&#xff1a;想用强大的Qwen2.5-7B大模型&#xff0c;但手机或嵌入式设备根本装不下几十GB的模型文件…

对比传统调试:vite-plugin-vue-devtools如何节省50%时间

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个对比测试项目&#xff0c;展示&#xff1a;1. 传统console.log调试方式 2. 浏览器原生DevTools调试 3. vite-plugin-vue-devtools调试。要求统计&#xff1a;1. 组件定位时…

智能实体识别服务:RaNER模型性能监控方案

智能实体识别服务&#xff1a;RaNER模型性能监控方案 1. 引言&#xff1a;AI 智能实体侦测服务的工程挑战 随着自然语言处理技术在信息抽取领域的广泛应用&#xff0c;命名实体识别&#xff08;Named Entity Recognition, NER&#xff09;已成为构建智能内容分析系统的核心能…

LangChain官网解析:如何用AI加速你的开发流程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个基于LangChain的AI辅助开发工具&#xff0c;能够自动生成Python代码片段&#xff0c;支持自然语言输入描述功能需求&#xff0c;自动调用LangChain API完成代码生成和调试…

Qwen2.5-7B新手指南:3步调用API,学生党1块钱体验

Qwen2.5-7B新手指南&#xff1a;3步调用API&#xff0c;学生党1块钱体验 1. 为什么选择Qwen2.5-7B做课程作业&#xff1f; 作为一名AI专业的学生&#xff0c;最近教授布置了对比三个大模型的作业。实验室GPU资源要排队两周&#xff0c;自己的笔记本根本跑不动7B参数的模型&am…

小白必看:第一次用Maven就报错怎么办?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个新手引导式解决方案&#xff1a;1) 卡通化界面 2) 分步图解指导 3) 语音解说 4) 错误模拟演示。内容包括&#xff1a;Maven基本概念、安装验证方法、环境变量设置可视化工…

AI智能实体侦测服务镜像测评:Cyberpunk风格WebUI实战体验

AI智能实体侦测服务镜像测评&#xff1a;Cyberpunk风格WebUI实战体验 1. 技术背景与选型动因 在信息爆炸的时代&#xff0c;非结构化文本数据&#xff08;如新闻、社交媒体内容、文档资料&#xff09;呈指数级增长。如何从海量文本中快速提取关键信息&#xff0c;成为自然语言…

电商大促期间JSTACK实战:解决订单超时问题全记录

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个电商订单超时故障模拟场景&#xff0c;包含&#xff1a;1. 模拟高并发下单场景的Java代码 2. 自动生成有Redis连接池阻塞问题的JSTACK日志 3. 分步骤的日志分析指引 4. 最…

RaNER模型歧义消解:同音词上下文判断部署优化实战

RaNER模型歧义消解&#xff1a;同音词上下文判断部署优化实战 1. 引言&#xff1a;中文命名实体识别的现实挑战 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;命名实体识别&#xff08;Named Entity Recognition, NER&#xff09; 是信息抽取的核心任务之一。尤…

零基础Linux Docker入门:从安装到第一个容器

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个面向Docker初学者的交互式教程项目&#xff0c;包含&#xff1a;1.基础概念图文解释 2.简单的Hello World容器示例 3.带提示的实践任务 4.常见问题解答。要求使用Markdown…

1小时用Access搭建客户关系管理原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个CRM系统原型&#xff0c;基于Access实现&#xff1a;1) 客户信息表&#xff1b;2) 联系记录表&#xff1b;3) 销售机会跟踪&#xff1b;4) 简易仪表盘。要求使用Acces…

WPS VBA vs 手动操作:效率提升对比分析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个对比测试项目&#xff0c;展示WPS VBA自动化与手动操作的效率差异。包括&#xff1a;1. 设计一个典型的数据处理任务&#xff1b;2. 分别实现手动操作步骤和VBA自动化脚本…

AI智能实体侦测服务显存优化技巧:CPU环境提速300%实战案例

AI智能实体侦测服务显存优化技巧&#xff1a;CPU环境提速300%实战案例 1. 背景与挑战&#xff1a;AI智能实体侦测服务的性能瓶颈 随着自然语言处理&#xff08;NLP&#xff09;技术在信息抽取领域的广泛应用&#xff0c;命名实体识别&#xff08;Named Entity Recognition, N…

Qwen2.5-7B企业级部署前必看:低成本验证方案

Qwen2.5-7B企业级部署前必看&#xff1a;低成本验证方案 引言 作为企业技术决策者&#xff0c;在考虑采购Qwen2.5企业版大模型前&#xff0c;您是否面临这样的困境&#xff1a;官方演示环境功能有限&#xff0c;无法满足自定义测试需求&#xff0c;而直接采购又担心投入产出比…

为什么with语句能让你的Python代码效率提升50%?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个性能对比测试&#xff0c;展示使用with语句和传统try-finally方式管理资源的区别。要求&#xff1a;1. 文件操作性能对比 2. 内存使用情况对比 3. 代码行数对比 4. 可读性…

告别繁琐!对比3种MongoDB下载安装方案效率

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个比较工具&#xff0c;能够&#xff1a;1) 自动测试三种MongoDB部署方式(本地安装、Docker、Atlas)的下载和启动时间&#xff1b;2) 生成可视化对比图表&#xff1b;3) 根据…

Python初学者必知:requirements.txt从零详解

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个交互式学习工具&#xff0c;通过示例演示requirements.txt的编写方法。包含&#xff1a;1) 基础语法讲解 2) 常见格式错误检查 3) 版本操作符模拟器 4) 虚拟环境创建向导 …