乐山市网站建设_网站建设公司_数据备份_seo优化
2026/1/10 13:26:59 网站建设 项目流程

你提供的这段代码是 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管理的关键组件。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询