尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Sa-Token 全局类与方法全解析:SaManager、SaHolder、SaFoxUtil 等核心对象的实战速查手册

Sa-Token 全局类与方法全解析:SaManager、SaHolder、SaFoxUtil 等核心对象的实战速查手册 Sa-Token 全局类与方法全解析SaManager、SaHolder、SaFoxUtil 等核心对象的实战速查手册【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token本篇是 Sa-Token 权限认证框架的全局对象速查手册系统梳理 Sa-Token 暴露给开发者的一等公民类全局组件管理器SaManager、上下文持有类SaHolder、路由匹配工具SaRouter、内部工具类SaFoxUtil、配置工厂SaTokenConfigFactory以及 SpringMVC 与 WebFlux/Reactor 环境下的专用工具类。读完本文你将掌握如何在不依赖 IOC 容器的纯 Java 环境下手动装配 Sa-Token 各组件、如何在任意代码位置拿到当前请求的 Request/Response 对象、如何在响应式链路中安全调用同步鉴权 API并理解这些工具类在框架源码中的真实实现机制。一、SaManager一切全局组件的统一入口SaManager是 Sa-Token 全局组件的注册中心与管理门面其定位在源码注释中写得很直白管理 Sa-Token 所有全局组件可通过此类快速获取、写入各种全局组件对象见 SaManager.java。框架运行期所需的配置、持久化、权限数据源、上下文、JSON 转换器、序列化器等全部通过它暴露是接入与扩展 Sa-Token 的第一站。1.1 核心 Getter/Setter 一览方法作用SaManager.getConfig()/setConfig(config)获取 / 设置全局配置对象SaTokenConfigSaManager.getSaTokenDao()/setSaTokenDao(dao)获取 / 设置数据持久化对象SaTokenDaoSaManager.getStpInterface()/setStpInterface(stp)获取 / 设置权限认证数据源StpInterfaceSaManager.getSaTokenContext()/setSaTokenContext(ctx)获取 / 设置上下文处理对象SaTokenContextSaManager.getSaTempTemplate()/setSaTempTemplate(t)获取 / 设置临时令牌认证模块Sa-Token-Temp临时认证SaManager.getSaJsonTemplate()/setSaJsonTemplate(t)获取 / 设置 JSON 转换器 BeanSaManager.getSaHttpTemplate()/setSaHttpTemplate(t)获取 / 设置 HTTP 请求处理 Bean详见 HTTP 请求扩展SaManager.getSaSerializerTemplate()/setSaSerializerTemplate(t)获取 / 设置序列化器 Bean自定义序列化方案SaManager.getSaSameTemplate()/setSaSameTemplate(t)获取 / 设置 Same-Token 同源校验模块 BeanSaManager.getSaTotpTemplate()/setSaTotpTemplate(t)获取 / 设置 TOTP 动态口令模块 Bean生成 / 验证一次性密码SaManager.getLog()/setLog(log)获取 / 设置日志输出对象SaLogSaManager.getStpLogic(type)获取指定账号类型的StpLogic不存在时自动创建并返回SaManager.getStpLogic(type, false)获取指定账号类型的StpLogic不存在时抛出异常SaManager.putStpLogic(stpLogic)向全局StpLogic集合中放入一个实例1.2 源码级原理懒加载与组件事件从源码结构看SaManager的所有 Getter 均采用双重检查锁 默认实现的懒加载策略首次调用时才创建组件例如getConfig()在config null时自动调用SaTokenConfigFactory.createConfig()创建默认配置getSaTokenDao()返回SaTokenDaoDefaultImpl内存实现getSaTokenContext()返回SaTokenContextForThreadLocal。这意味着即使不做任何手工装配框架也能以零配置状态跑起来。而所有 Setter 在写入组件的同时会触发全局事件SaTokenEventCenter.doRegisterComponent(组件名, 实例)供监听器感知组件变更setConfig(config)还额外做了三件事若配置了isPrint则调用SaFoxUtil.printSaToken()打印启动 Banner若isLogtrue且未显式配置isColorLog则通过SaFoxUtil.isCanColorLog()自动探测终端是否支持彩色日志触发doSetConfig全局事件并提前初始化一次StpUtil的StpLogic。其中setSaTokenDao在替换持久化组件时还会先调用旧实例的destroy()、再调用新实例的init()确保数据源切换时资源被正确回收与重建。1.3 StpLogic 多账号体系的管理StpLogic是 Sa-Token 登录认证逻辑的载体SaManager用ConcurrentHashMap维护loginType - StpLogic的映射支持多账号体系并行。getStpLogic(String loginType)在查不到时会走自创建模式通过SaStrategy.instance.createStpLogic自动创建并注册而getStpLogic(type, false)是严格校验模式查不到会抛出SaTokenException错误码CODE_10002。源码注释也指出了两种常见踩坑场景loginType拼写错误以及自定义StpUtil因静态类未被触发初始化而尚未注册解决办法在 main 方法中调用一次或用Component让容器启动时扫描。注意侦听器注册请使用SaTokenEventCenter.registerListener(listener)参数签名模块请使用SaSignManager.getSaSignTemplate()见 参数签名 章节。二、SaHolder任意代码位置获取当前环境对象SaHolder是 Sa-Token 的上下文持有类通过它可以在不依赖 Spring、不注入 Servlet API 的情况下快速拿到当前请求环境的各种对象源码见 SaHolder.javaSaHolder.getContext(); // 获取当前请求的 SaTokenContext 上下文对象 SaHolder.getRequest(); // 获取当前请求的 [Request] 包装对象 SaHolder.getResponse(); // 获取当前请求的 [Response] 包装对象 SaHolder.getStorage(); // 获取当前请求的 [Storage] 包装对象请求级临时存储 SaHolder.getApplication(); // 获取全局 SaApplication 对象源码显示getContext()直接委托给SaManager.getSaTokenContext()getRequest()/getResponse()/getStorage()则从该上下文中取当前请求的包装对象getApplication()返回全局单例SaApplication.defaultInstance。这里获取到的SaRequest/SaResponse是 Sa-Token 自定义的抽象层其底层适配器由当前集成环境Servlet、Reactor、Solon、JFinal 等注入。因此核心代码中只要面向SaHolder编程就能天然实现多框架移植——这是它在微服务、WebFlux 场景下被广泛使用的原因。三、SaRouter路由匹配与拦截式鉴权SaRouter是 Sa-Token 的路由匹配工具类核心能力是在代码中对路径模式做拦截式鉴权常用于全局过滤器、拦截器中按路由规则放行或校验权限。其典型用法包括SaRouter.match(/admin/**, r - StpUtil.checkRole(admin)); // 匹配路径后执行鉴权 SaRouter.match(/user/**, r - StpUtil.checkLogin()); // 登录校验 SaRouter.match(/public/**).stop(); // 直接跳过放行 SaRouter.match(/**, r - StpUtil.checkLogin()) .notMatch(/login, /register) // 排除放行路径 .execute();它支持通配符匹配、notMatch反向排除、stop终止匹配链等是 路由拦截式鉴权 章节的主角。值得注意的是SaRouter内部的模糊匹配能力实际复用了SaFoxUtil.vagueMatch()两者常配合出现在拦截器编排中。详细的路径匹配语法与拦截器接入方式请直接参阅该章节。四、SaFoxUtil开箱即用的内部工具集SaFoxUtil是 Sa-Token 的静态内部工具类源码见 SaFoxUtil.java覆盖字符串、URL、集合、类型转换、日期、模糊匹配等常用操作可直接在业务代码中调用SaFoxUtil.printSaToken(); // 打印 Sa-Token 版本字符画启动 Banner SaFoxUtil.getRandomString(8); // 生成指定长度的随机字符串基于 SecureRandom 的 CSPRNG SaFoxUtil.isEmpty(str); // 指定字符串是否为 null 或空字符串 SaFoxUtil.isNotEmpty(str); // 指定字符串是否非 null 且非空 SaFoxUtil.equals(a, b); // 比较两个对象是否相等 SaFoxUtil.getMarking28(); // 以当前时间戳 随机 int 拼接一个随机字符串 SaFoxUtil.formatDate(date); // 将日期格式化为 yyyy-MM-dd HH:mm:ss 字符串 SaFoxUtil.searchList(dataList, prefix, keyword, start, size, sortType); // 从集合中按前缀/关键字查询数据 SaFoxUtil.searchList(dataList, start, size, sortType); // 从集合中取指定段数据 SaFoxUtil.vagueMatch(patt, str); // 字符串模糊匹配支持 * 通配符 SaFoxUtil.getValueByType(obj, cs); // 将指定值转换为指定类型 SaFoxUtil.joinParam(url, parameStr); // 在 url 上拼接 kv 参数并返回 SaFoxUtil.joinParam(url, key, value); // 在 url 上拼接 kv 参数并返回 SaFoxUtil.joinSharpParam(url, parameStr); // 在 url 上拼接锚参数# 后 SaFoxUtil.joinSharpParam(url, key, value); // 在 url 上拼接锚参数 SaFoxUtil.arrayJoin(arr); // 将数组所有元素用逗号拼接 SaFoxUtil.isUrl(str); // 用正则表达式判断字符串是否为 URL SaFoxUtil.encodeUrl(str); // URL 编码 SaFoxUtil.decoderUrl(str); // URL 解码 SaFoxUtil.convertStringToList(str); // 按逗号分隔符将字符串转为字符串集合 SaFoxUtil.convertListToString(list); // 按逗号将集合连接成字符串 SaFoxUtil.convertStringToArray(str); // String 转 Array按逗号切割 SaFoxUtil.convertArrayToString(arr); // Array 转 String按逗号切割 SaFoxUtil.emptyList(); // 返回一个空集合 SaFoxUtil.toList(... strs); // String 数组转集合几个值得展开的实现细节getRandomString的安全性源码使用静态共享的SecureRandomCSPRNG线程安全从 62 个字符集中采样适合生成 token 片段、盐值等安全敏感随机串另有一个getRandomNumber(min, max)可生成指定区间随机 int。vagueMatch的性能优化源码在表达式不含*时直接退化为equals比较注释称这样可以使速度提升 200 倍左右含*时才进入基于动态规划的双指针匹配算法用于鉴权路由的通配符校验。joinParam的边界处理源码对?不存在、?在末尾、?在中间三种情况分别处理自动补齐分隔符避免拼接出畸形 URL。getValueByType的类型转换覆盖 String 与 8 大基础类型含包装类的转换是SaTokenConfigFactory反射赋值的底层转换器。searchList的分页查询支持prefixkeyword过滤、start起始位置、size条数-1代表一直取到末尾以及sortType正/反序可用于后端分页搜索类场景。五、SaTokenConfigFactory从 properties 文件构建配置对象SaTokenConfigFactory是配置对象工厂类源码见 SaTokenConfigFactory.java专为非 IOC 环境如纯 Java 项目、单元测试设计让你可以脱离 Spring Boot 的自动配置手动从 properties 文件构建SaTokenConfig。5.1 三步接入流程第一步在项目根目录classpath 下创建配置文件sa-token.properties# token 名称 (同时也是 cookie 名称) tokenNamesatoken # token 有效期单位秒默认 30 天-1 代表永久有效 timeout2592000 # token 最低活跃频率单位秒如果 token 超过此时间没有访问系统就会被冻结默认 -1 代表不限制永不冻结 activeTimeout-1 # 是否允许同一账号多地同时登录 为 true 时允许一起登录, 为 false 时新登录挤掉旧登录 isConcurrenttrue # 在多人登录同一账号时是否共用一个 token 为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token isSharefalse # token 风格默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik tokenStyleuuid # 是否输出操作日志 isLogfalse第二步指定配置文件路径并创建配置对象// 设置配置文件地址 SaTokenConfigFactory.configPath sa-token.properties; // 获取配置信息到 config 对象 SaTokenConfig config SaTokenConfigFactory.createConfig(); // 注入到 SaManager 中 SaManager.setConfig(config);configPath默认值就是sa-token.properties因此不手动指定时也会自动读取该文件也可以通过createConfig(String path)指定任意 classpath 路径。5.2 源码级原理反射装配从源码看createConfig()的装配链路是readPropToMap(path)用ClassLoader.getResourceAsStream从 classpath 读取 properties 文件并转成MapString, String随后initPropByMap(map, new SaTokenConfig())通过反射遍历SaTokenConfig的字段按字段名从 Map 中取值再用SaFoxUtil.getValueByType()将字符串转换为字段的真实类型后注入。这意味着sa-token.properties中可写的键名与SaTokenConfig的字段名一一对应若想扩展更多配置项只需了解该配置类字段即可。当配置文件缺失时方法返回一个全默认值的空配置不抛异常文件读取失败或反射赋值失败时分别抛出错误码CODE_10021、CODE_10022的SaTokenException。该工厂同样是SaManager.getConfig()懒加载时的默认配置来源因此在任何集成环境下它都在幕后工作。六、SpringMVCUtilServlet 环境下的 Request/Response 快捷获取SpringMVCUtil是 SpringMVC 操作工具类位于sa-token-spring-boot-starter包源码见 SpringMVCUtil.java用于快速获取原生 Servlet 对象SpringMVCUtil.getRequest(); // 获取本次请求的 HttpServletRequest 对象 SpringMVCUtil.getResponse(); // 获取本次请求的 HttpServletResponse 对象 SpringMVCUtil.isWeb(); // 判断当前是否处于 Web 上下文中源码实现基于 Spring 的RequestContextHolder.getRequestAttributes()取得ServletRequestAttributes后取出原生 request/response当不在 Web 上下文如定时任务线程中调用时会抛出NotWebContextException异常因此调用前应先用isWeb()做环境判断。与之相对如果你需要的是 Sa-Token 抽象过的SaRequest/SaResponse可跨框架应优先使用SaHolder系列方法。七、SaReactorHolder 与 SaReactorSyncHolderReactor 响应式环境下的上下文方案在 WebFlux 响应式场景下ServerWebExchange不再与线程绑定无法用 ThreadLocal 直接存取。Sa-Token 为此提供了SaReactorHolder与SaReactorSyncHolder两个工具类位于sa-token-reactor-spring-boot-starter包源码见 SaReactorHolder.java 与 SaReactorSyncHolder.java。7.1 异步方式SaReactorHolderSaReactorHolder将ServerWebExchange与WebFilterChain写入Reactor Context流式上下文随响应式链路传递// 异步方式获取 ServerWebExchange 对象 SaReactorHolder.getMonoExchange().map(e - { System.out.println(e); return e; }); // 在 Mono 链中调用 Sa-Token 同步 API返回 MonoRController 中需 return return SaReactorHolder.sync(() - { StpUtil.checkLogin(); return SaResult.ok(); });其中getMonoExchange()通过Mono.deferContextual从上下文中取出当前 exchange 并包装为MonoServerWebExchange而sync(函数式)则是响应式环境下的桥接利器——它从 Reactor Context 中取出 exchange 临时写入同步上下文SaReactorSyncHolder在函数内执行StpUtil.checkLogin()等同步 API执行完毕在finally中清除上下文。这也是官方推荐的在 WebFlux Controller 中调用 Sa-Token 同步方法的标准姿势Controller 需return这个 Mono。7.2 同步方式SaReactorSyncHolderSaReactorSyncHolder面向 WebFilter 等仍持有当前请求对象的场景以手动设置上下文 手动清理的方式工作SaReactorSyncHolder.setContext(exchange); // 写入当前请求的 ServerWebExchange SaReactorSyncHolder.getExchange(); // 获取当前请求的 ServerWebExchange SaReactorSyncHolder.clearContext(); // 清除当前上下文 SaReactorSyncHolder.setContext(exchange, () - {}); // 在指定 exchange 上下文中执行代码块并返回结果它本质上是在响应式链路中开辟一个局部的同步上下文窗口底层使用 ThreadLocal 存取因此必须保证 set 与 clear 成对出现或在回调式重载中由框架自动清理避免跨线程污染。7.3 两种方式如何选择场景推荐工具Controller 的 Mono 链中调用同步鉴权 APISaReactorHolder.sync(() - ...)响应式链中拿到当前ServerWebExchange做自定义处理SaReactorHolder.getMonoExchange()自定义 WebFilter / Handler 中已有 exchange 对象SaReactorSyncHolder.setContext/getExchange/clearContext在指定 exchange 上下文中执行一段代码SaReactorSyncHolder.setContext(exchange, () - {})八、小结全局对象速查索引类所属模块典型用途SaManagersa-token-core全局组件注册 / 获取多账号 StpLogic 管理SaHoldersa-token-core任意位置获取 Request / Response / Storage / ApplicationSaRoutersa-token-core路由匹配与拦截式鉴权SaFoxUtilsa-token-core通用工具方法随机串、URL、集合、类型转换等SaTokenConfigFactorysa-token-core从sa-token.properties构建配置对象非 IOC 环境SpringMVCUtilsa-token-spring-boot-starterServlet 环境下获取原生 Request / ResponseSaReactorHolder/SaReactorSyncHoldersa-token-reactor-spring-boot-starterWebFlux 响应式环境下获取 / 桥接 ServerWebExchange这些全局对象覆盖了 Sa-Token 从配置装配到运行期访问的完整链路用SaTokenConfigFactory装配配置、用SaManager注册与获取各组件、用SaHolder访问当前环境、用SaRouter做路由鉴权、用SaFoxUtil处理通用逻辑再针对 Servlet 与响应式环境选择对应的专用工具类。熟悉这一套对象体系是在任何框架集成、任何代码位置熟练驾驭 Sa-Token 的基础。若需要进一步深入路由拦截的完整配置与进阶用法可继续阅读 路由拦截式鉴权 章节。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表