news 2026/9/1 22:25:23

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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管理的关键组件。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/15 2:07:03

Qwen2.5-7B智能写作对比:云端3小时=本地3天,效率飙升

Qwen2.5-7B智能写作对比&#xff1a;云端3小时本地3天&#xff0c;效率飙升 1. 为什么自媒体团队需要云端AI写作测试 作为自媒体内容创作者&#xff0c;我们经常需要测试不同AI模型的写作效果。传统方式是在本地电脑上逐个运行模型对比&#xff0c;但会遇到两个致命问题&…

作者头像 李华
网站建设 2026/8/23 0:08:31

用NETTOPLCSIM在1小时内搭建智能仓储原型系统

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 构建一个智能仓储快速原型系统&#xff0c;功能包括&#xff1a;1) 可视化仓库布局编辑器 2) AGV路径规划模拟 3) 库存动态显示 4) 异常情况注入测试。要求使用MODBUS TCP协议仿真…

作者头像 李华
网站建设 2026/8/21 18:40:28

Qwen2.5-7B代码解释器:云端Jupyter集成,2块钱debug

Qwen2.5-7B代码解释器&#xff1a;云端Jupyter集成&#xff0c;2块钱debug 引言&#xff1a;程序员的AI调试助手 刚学编程时最怕什么&#xff1f;不是写代码&#xff0c;而是遇到报错却看不懂&#xff01;那些密密麻麻的错误信息就像天书&#xff0c;新手往往手足无措。传统解…

作者头像 李华
网站建设 2026/8/21 18:40:29

Git小乌龟零基础入门:从安装到第一个提交

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个面向新手的Git小乌龟交互式学习应用。从安装向导开始&#xff0c;逐步引导用户完成&#xff1a;1) 软件安装和基本配置&#xff1b;2) 创建或克隆第一个仓库&#xff1b;3…

作者头像 李华
网站建设 2026/8/21 18:40:30

AI智能实体侦测服务冷启动问题:首次加载延迟优化技巧

AI智能实体侦测服务冷启动问题&#xff1a;首次加载延迟优化技巧 1. 背景与挑战&#xff1a;AI服务的“第一印象”至关重要 在现代AI应用中&#xff0c;用户体验往往从第一次交互开始。对于基于深度学习的智能服务而言&#xff0c;冷启动阶段的性能表现直接影响用户留存率和产…

作者头像 李华
网站建设 2026/8/29 22:08:06

传统VS AI:解决APK兼容性问题的效率对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个对比工具&#xff0c;模拟传统手动解决APK兼容性问题的流程和AI辅助流程。工具应记录两种方法的时间消耗、步骤复杂度和最终效果。提供可视化数据对比&#xff0c;并允许用…

作者头像 李华