在使用Sa-Token框架实现多账号体系时,当后端服务重启后,系统报错"未能获取对应StpLogic,type=XXX"。这种情况通常发生在配置了Redis持久化存储的场景下,特别是在多账号体系中使用自定义的StpLogic时。
这个问题的本质在于Sa-Token的多账号体系实现机制与Redis持久化存储之间的协同工作方式。当开发者定义了一个新的StpLogic实例(如ADMIN = new StpLogic("ADMIN")
)时,这个定义仅存在于JVM内存中。服务重启后,虽然Redis中存储的Token数据仍然存在,但JVM中的StpLogic实例定义已经丢失。
原本实现代码:
java
package com.example.auth.service;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* StpLogic 门面类,管理项目中所有的 StpLogic 账号体系
*/
public class StpKit {
public static final String USER_TYPE = "client";
public static final String xxx_TYPE = "xxx";
/**
* 默认原生会话对象
*/
public static final StpLogic DEFAULT = StpUtil.stpLogic;
/**
* User 会话对象,管理 client 类型所有账号的登录、权限认证
*/
public static final StpLogic USER = new StpLogic(USER_TYPE);
/**
* xxx 会话对象
*/
public static final StpLogic xxx = new StpLogic(xxx_TYPE);
}
解决方案
在StpLogic门面类上加入@Component注解即可。
java
package com.example.auth.service;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.stereotype.Component;
/**
* StpLogic 门面类,管理项目中所有的 StpLogic 账号体系
*/
@Component
public class StpKit {
public static final String USER_TYPE = "client";
public static final String xxx_TYPE = "xxx";
/**
* 默认原生会话对象
*/
public static final StpLogic DEFAULT = StpUtil.stpLogic;
/**
* User 会话对象,管理 client 类型所有账号的登录、权限认证
*/
public static final StpLogic USER = new StpLogic(USER_TYPE);
/**
* xxx 会话对象
*/
public static final StpLogic xxx = new StpLogic(xxx_TYPE);
}