
Sa-Token SaStrategy 全局策略核心逻辑代理封装与自定义扩展指南【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-TokenSaStrategy全局策略是 Sa-Token 框架中统一定义关键性逻辑算法的入口以全局单例的形式将 Token 生成、Session 创建、唯一性校验、自动续期、配置读取等核心行为抽象为可替换的函数式策略。本文以 sa-token-doc-new/docs/api/sa-strategy.md 为骨架结合 SaStrategy.java 源码与 SaStrategyTest.java 测试用例完整讲解每一个内置策略的默认实现、重写方法与应用场景读完即可按需定制 Sa-Token 的核心行为如自定义 Token 算法、从数据库动态加载配置。一、SaStrategy 是什么核心逻辑的代理封装Sa-Token 框架内部分散着大量关键性算法如何创建 Token、如何创建 Session、如何判断权限集合、如何生成不重复的 token、是否续期、如何匹配路由……在引入 SaStrategy 之前这些逻辑散落在框架各处开发者想要定制只能改动框架源码。SaStrategy 的设计目标正如 SaStrategy.java 的类注释所述此类统一定义框架内的一些关键性逻辑算法方便开发者进行按需重写。它的核心形态是一个持有大量函数式接口字段的全局单例全局单例通过public static final SaStrategy instance new SaStrategy();暴露构造器私有全框架共享同一实例源码见 SaStrategy.java函数式字段每个策略都是一个 Java 函数式接口BiFunction、Function、Supplier等默认提供框架内置实现开发者可直接为字段赋值覆盖set 连缀风格每个策略字段都配有一个返回this的setXxx方法支持链式调用同时保留对旧版SaStrategy.me的兼容已标注Deprecated建议使用instance见 SaStrategy.java。策略接口统一收拢在cn.dev33.satoken.fun.strategy包下见 fun/strategy 目录包括SaCreateTokenFunction、SaCreateSessionFunction、SaHasElementFunction、SaGenerateUniqueTokenFunction、SaAutoRenewFunction、SaCreateStpLogicFunction、SaRouteMatchFunction、SaCorsHandleFunction、SaGetSaTokenConfigFunction以及 SaRequest/SaResponse/SaStorage 创建策略等。从使用方式看框架内部各模块通过SaStrategy.instance.xxx调用这些策略例如 StpLogic.java 中createToken、StpLogic.java 中hasElement因此只要替换对应字段框架所有调用方会一并生效——这正是代理封装的含义策略层是框架逻辑的唯一入口替换策略即替换行为。二、核心策略详解默认实现与可替换行为以下 10 项策略完整覆盖 sa-strategy.md 文档中的核心策略清单并逐一补充源码级默认实现说明。2.1 createToken创建 Token 的策略函数签名BiFunctionObject, String, String参数为[账号id, 账号类型]返回 Token 字符串重写入口setCreateToken(...)。文档中默认实现简写为xxxxx-xxxxx-xxxxx-xxxxxUUID 形态。对照源码实际默认实现远比这丰富它会读取该账号体系配置中的tokenStyle按风格生成不同格式的 Token见 SaStrategy.javatokenStyle 配置值生成结果测试断言见 SaStrategyTestuuid默认UUID.randomUUID().toString()形如xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx含-断言包含-simple-uuidUUID 去掉所有-固定 32 位断言长度为 32 且不含-random-3232 位随机字符串断言长度为 32random-6464 位随机字符串断言长度为 64random-128128 位随机字符串断言长度为 128tik2位随机 _ 14位随机 _ 16位随机 __断言以__结尾其他非法值打印 warn 日志并回退为 UUID断言回退结果含-以上行为在 SaStrategyTest.java 的createToken_byTokenStyle测试中逐一验证。自定义示例如接入 JWT 或自研 token 格式SaStrategy.instance.setCreateToken((loginId, loginType) - { // 这里可以基于 loginId、loginType 自定义生成算法例如拼接业务前缀 return MY- loginId - System.currentTimeMillis(); });2.2 createSession创建 Session 的策略函数签名FunctionString, SaSession参数为[SessionId]返回SaSession实例重写入口setCreateSession(...)。默认实现sessionId - new SaSession(sessionId)见 SaStrategy.java即创建框架标准的SaSession。测试createSession_hasElement_generateUniqueToken中验证默认创建的 Session 能正确保留传入的 id见 SaStrategyTest.java。典型应用当项目需要自定义 Session 实现例如继承SaSession扩展字段可在此策略中返回自定义子类SaStrategy.instance.setCreateSession((sessionId) - { return new MySaSession(sessionId); // MySaSession 继承自 SaSession });2.3 sessionClassType反序列化 SaSession 的默认类型类型volatile Class? extends SaSession默认值SaSession.class见 SaStrategy.java。该字段用于指定从持久化层反序列化SaSession时使用的类型。若 2.2 中自定义了 Session 子类通常需要同步将此字段改为对应子类的Class保证反序列化后仍是自定义类型。注意这是一个直接字段赋值volatile保证多线程可见性文档未提供对应 set 方法赋值方式为SaStrategy.instance.sessionClassType MySaSession.class;。2.4 hasElement集合模糊匹配策略函数签名BiFunctionListString, String, Boolean参数为[集合, 元素]返回是否命中重写入口setHasElement(...)。文档中的默认实现简写为return false仅示意可替换。实际默认实现是一个先精确匹配、后通配符模糊匹配的两段式算法见 SaStrategy.java集合为空null或size() 0直接返回false先尝试list.contains(element)精确匹配命中即返回true遍历集合用SaFoxUtil.vagueMatch(patt, element)逐个做通配符匹配。典型场景权限/角色校验。例如角色列表为[admin, user:*]时元素user:1001可通过user:*通配命中。测试 SaStrategyTest.java 验证了null、空集合返回 false、精确匹配与通配匹配均正确。该策略被StpUtil.hasElement(...)间接调用StpLogic.hasElement委托给SaStrategy.instance.hasElement见 StpLogic.java进而影响hasRole、hasPermission等权限判断逻辑。2.5 generateUniqueToken生成唯一式 Token 的算法函数签名SaGenerateUniqueTokenFunction参数为[元素名称, 最大尝试次数, 创建 token 函数, 检查 token 函数]返回唯一 Token函数式接口定义见 SaGenerateUniqueTokenFunction.java重写入口setGenerateUniqueToken(...)。文档中的默认实现简写为return xxxxxx。真实默认实现是一个循环生成 唯一性校验 失败重试算法见 SaStrategy.java调用createTokenFunction.get()生成一个 token若maxTryTimes -1表示不做唯一性验证直接返回否则调用checkTokenFunction.apply(token)返回true说明可用立即返回循环超过maxTryTimes次仍未成功抛出SaTokenException提示生成算法过于简单或资源池已耗尽。该接口的四个参数语义见 SaGenerateUniqueTokenFunction.java为elementName用于组织异常提示信息maxTryTimes最大尝试次数createTokenFunction负责生成checkTokenFunction负责校验唯一性返回 true 表示可用。框架内真实调用链StpUtil.login()创建新 token 时会执行该策略见 StpLogic.java传入的checkTokenFunction为getLoginIdNotHandle(tokenValue) null即该 token 在数据源中查不到任何账号才认为可用该策略同样被用于 SSO 的 ticket、临时 tokenSaTempTemplate等需要保证唯一性的元素的生成。测试验证见 SaStrategyTest.java生成器依次产出tk-1/tk-2/tk-3校验器要求以3结尾最终返回tk-3固定生成same且校验器永远返回 false、maxTryTimes2时抛出SaTokenExceptionmaxTryTimes-1时跳过校验直接返回。2.6 autoRenew是否自动续期 active-timeout 的策略函数签名FunctionStpLogic, Boolean参数为当前StpLogic实例返回true自动续期、false不自动续期重写入口setAutoRenew(...)。默认实现stpLogic - stpLogic.getConfigOrGlobal().getAutoRenew()见 SaStrategy.java即直接读取配置项autoRenew默认开启。文档特别强调每次续期前都会执行可以加入动态判断逻辑——这意味着该策略的执行频率很高可用于在续期前加入自定义业务判断。典型应用例如要求仅在工作时间自动续期或VIP 账号自动续期、普通账号不续期SaStrategy.instance.setAutoRenew((stpLogic) - { // 例读配置为 true但可附加业务动态判断 return stpLogic.getConfigOrGlobal().getAutoRenew(); });该策略在 StpLogic.java 附近被调用作为会话活跃度续期的开关。测试autoRenew_createStpLogic_andNotImplStrategies验证了配置autoRenewfalse时策略返回false见 SaStrategyTest.java。2.7 createStpLogic创建 StpLogic 的算法函数签名SaCreateStpLogicFunction参数为[账号体系标识 loginType]返回创建好的StpLogic对象重写入口setCreateStpLogic(...)。默认实现loginType - new StpLogic(loginType)见 SaStrategy.java。StpLogic是每个账号体系如login、user、admin的逻辑封装Sa-Token 支持多账号体系并行鉴权此策略决定了每个loginType对应的StpLogic如何创建。典型应用当项目继承StpLogic并扩展方法时通过重写此策略让所有账号体系都使用自定义子类SaStrategy.instance.setCreateStpLogic((loginType) - { return new MyStpLogic(loginType); // MyStpLogic 继承 StpLogic });测试中验证了默认实现创建的StpLogic能正确携带loginType且链式 set 后可生成chain-app这种带前缀的 loginType见 SaStrategyTest.java。2.8 routeMatcher路由匹配策略函数签名SaRouteMatchFunction参数为[pattern, path]返回是否匹配重写入口SaStrategy.instance.routeMatcher ...文档未单独提供 set 方法需直接字段赋值。这是少数默认未实现的策略之一默认实现直接抛出NotImplException错误码CODE_12401未实现具体路由匹配策略见 SaStrategy.java。它由SaRouter路由拦截模块消费SaRouter.java具体实现由各集成插件Servlet、WebFlux、Solon 等注入。测试中确认默认状态抛出NotImplException见 SaStrategyTest.java。普通业务开发者一般不需要修改此策略除非要定制路由通配符语法。2.9 corsHandleCORS 策略处理函数函数签名SaCorsHandleFunction参数为[请求包装对象, 响应包装对象, 数据读写对象]重写入口SaStrategy.instance.corsHandle ...直接字段赋值。默认实现为空操作(req, res, sto) - {}见 SaStrategy.java即默认不处理 CORS测试验证空实现可正常执行、不抛异常见 SaStrategyTest.java。当项目需要基于请求/响应包装对象动态写入 CORS 响应头时可在此策略内完成。更常见的 CORS 解决方案可参考仓库文档中的全局过滤器配置见 sa-token-doc/up/global-filter.md。2.10 getSaTokenConfig获取 SaTokenConfig 的策略函数签名SaGetSaTokenConfigFunction其本质是SupplierSaTokenConfig见 SaGetSaTokenConfigFunction.java默认值null表示不启用使用框架内置逻辑重写入口setGetSaTokenConfig(...)。这是文档重点介绍、也最具实战价值的策略详见下一节专章。补充未列出的其他策略源码中还定义了createSaRequest/createSaResponse/createSaStorage三个上下文对象创建策略分别对应CODE_12402/CODE_12403/CODE_12404默认抛NotImplException由各集成层实现见 SaStrategy.java。它们不属于业务定制范围通常无需修改。三、getSaTokenConfig从外部数据源动态读取配置3.1 默认配置加载链路当getSaTokenConfig为null时SaManager.getConfig()走框架内置逻辑见 SaManager.java若全局config字段已初始化直接返回若为空在类锁内通过SaTokenConfigFactory.createConfig()创建配置默认读取sa-token.properties等配置文件返回并缓存到config字段。3.2 启用自定义策略后的行为变化一旦执行setGetSaTokenConfig(...)赋值非 nullSaManager.getConfig()的每次调用都会直接执行此策略并返回其结果完全绕过内置加载链路见 SaManager.java 的优先分支。测试setCreateContextAndConfigChainMethods验证了策略返回的SaTokenConfig会被原样读取见 SaStrategyTest.java。3.3 官方使用示例文档原版可直接复制运行SaStrategy.instance.setGetSaTokenConfig(() - { // 从数据库读取配置自行做好缓存 SaTokenConfig config new SaTokenConfig(); config.setTokenName(satoken); config.setTimeout(30 * 24 * 60 * 60); return config; });3.4 两条强制注意点根据文档与源码双重确认使用该策略必须遵守严禁递归调用策略内部不要调用SaManager.getConfig()否则每次调用都会再次进入本策略形成无限递归源码注释与 SaGetSaTokenConfigFunction.java 均明确警告必须自行缓存启用后SaManager.getConfig()每次调用都会执行策略若每次都在策略内查询数据库将带来明显性能开销。建议在策略内加一层缓存内存缓存、Caffeine 等并在配置变更时主动刷新。典型应用场景需要将 token 有效期、token 名称等配置动态化管理存于数据库、配置中心改动后无需重启应用即可生效。这是动态配置需求的标准落地方式官方描述为适用于需要从数据库等外部数据源动态读取配置的场景。四、重写策略set 连缀风格与实操要点4.1 所有重写入口一览文档给出 7 个 set 方法全部采用返回this的连缀风格源码见 SaStrategy.java可一行链式重写多个策略SaStrategy.instance .setCreateToken(createToken) // 重写创建 Token 的策略 .setCreateSession(createSession) // 重写创建 Session 的策略 .setHasElement(hasElement) // 重写集合模糊匹配策略 .setGenerateUniqueToken(generateUniqueToken)// 重写生成唯一 token 的策略 .setCreateStpLogic(createStpLogic) // 重写创建 StpLogic 的策略 .setAutoRenew(autoRenew) // 重写是否自动续期策略 .setGetSaTokenConfig(getSaTokenConfig); // 重写获取 SaTokenConfig 的策略除文档列出的 7 个方法外源码还提供setCreateSaRequest、setCreateSaResponse、setCreateSaStorage三个上下文创建策略的重写方法见 SaStrategy.java主要用于集成层定制。4.2 链式调用的测试验证测试 SaStrategyTest.java 验证了链式 set 的行为每个 set 方法返回的都是SaStrategy自身assertSame(strategy, strategy.setGenerateUniqueToken(...))替换后createToken返回自定义值custom-token、createSession生成custom-sid前缀 Session、hasElement恒为true、autoRenew侧生效AtomicBoolean被置为 true、createStpLogic生成chain-app。4.3 实操要点重写位置建议在应用启动阶段如 Spring Boot 的Configuration类、CommandLineRunner或静态初始化块统一完成重写避免运行时动态更换导致行为不一致全局生效instance是全局单例任何位置的重写都会影响整个框架所有账号体系重写前请确认不会影响其他模块如 SSO、OAuth2 插件同样消费这些策略字段 vs 方法createToken等策略既有公开字段也有 set 方法sessionClassType、routeMatcher、corsHandle没有对应 set 方法需直接字段赋值。新代码统一推荐使用setXxx方法 instanceme已废弃。五、完整落地示例一个自定义 Token 动态配置的综合配置类综合以上策略给出一个完整的可运行示例以 Spring Boot 风格为例一次性演示createToken、hasElement、getSaTokenConfig三个策略的组合使用import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.strategy.SaStrategy; import org.springframework.context.annotation.Configuration; Configuration public class SaTokenStrategyConfig { public SaTokenStrategyConfig() { // 1、自定义 Token 生成算法业务前缀 时间戳 SaStrategy.instance.setCreateToken((loginId, loginType) - MY- loginType - loginId - System.currentTimeMillis() ); // 2、定制权限模糊匹配追加自定义通配规则 SaStrategy.instance.setHasElement((list, element) - { if (list null || list.size() 0) { return false; } if (list.contains(element)) { return true; } // 追加一条自定义规则element 以 list 中任一元素开头即视为匹配 for (String patt : list) { if (element.startsWith(patt)) { return true; } } return false; }); // 3、从数据库动态读取配置内部需做好缓存严禁回调 SaManager.getConfig() SaStrategy.instance.setGetSaTokenConfig(() - { SaTokenConfig config new SaTokenConfig(); config.setTokenName(satoken); config.setTimeout(30 * 24 * 60 * 60); // 30 天单位秒 // 实际项目中可改为从数据库/配置中心读取 return config; }); } }六、小结策略层定位与适用边界定位SaStrategy 是 Sa-Token 核心逻辑的代理封装层把分散的算法收敛为可替换的函数式策略字段框架内部所有关键调用点Token 创建、Session 创建、权限匹配、唯一性生成、活跃续期、配置读取等都统一经过该单例适用场景自定义 Token 格式createToken、自定义 Session 类型createSessionsessionClassType、定制权限通配规则hasElement、控制自动续期行为autoRenew、多账号体系定制createStpLogic、外部数据源动态配置getSaTokenConfig不适用边界routeMatcher、createSaRequest/createSaResponse/createSaStorage属于集成层职责默认抛NotImplException由各集成插件实现业务层无需也不应随意替换。延伸阅读关于SaTokenConfig各配置项如tokenStyle、autoRenew、timeout的完整说明可参见 sa-token-doc/use/config.mdSession 相关 API 见 sa-token-doc/api/sa-session.mdDAO 数据源扩展见 sa-token-doc/api/sa-token-dao.md。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考