refactor: 重构部分 sa-token-redis 插件,适配 SPI 机制

This commit is contained in:
click33 2025-02-21 21:27:34 +08:00
parent a4c9dc1e68
commit 0d9fed1558
27 changed files with 129 additions and 129 deletions

View File

@ -111,7 +111,7 @@
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis</artifactId>
<artifactId>sa-token-redis-template</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
@ -194,6 +194,16 @@
<artifactId>sa-token-temp-jwt</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jackson</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-template-jdk-serializer</artifactId>
<version>${revision}</version>
</dependency>
<!-- endregion-->
</dependencies>

View File

@ -15,6 +15,8 @@
*/
package cn.dev33.satoken.plugin;
import cn.dev33.satoken.SaManager;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
@ -27,12 +29,32 @@ import java.util.ServiceLoader;
*/
public class SaTokenPluginLoader {
/**
* 是否已经加载过插件
*/
public static boolean isLoader = false;
/**
* 所有插件的集合
*/
public static List<SaTokenPlugin> pluginList;
/**
* 初始化插件
* 初始化加载所有插件多次调用只会执行一次
*/
public static void init() {
if(isLoader) {
return;
}
loaderPlugins();
isLoader = true;
}
/**
* 根据 SPI 机制加载所有插件
*/
public static void loaderPlugins() {
SaManager.getLog().info("SPI 插件加载开始 ...");
List<SaTokenPlugin> list = new ArrayList<>();
ServiceLoader<SaTokenPlugin> plugins = ServiceLoader.load(SaTokenPlugin.class);
for (SaTokenPlugin plugin : plugins) {
@ -40,6 +62,7 @@ public class SaTokenPluginLoader {
list.add(plugin);
}
pluginList = list;
SaManager.getLog().info("SPI 插件加载结束 ...");
}
}

View File

@ -393,7 +393,7 @@ public class SaSession implements SaSetValueInterface, Serializable {
* 获取此Session的剩余存活时间 (单位: )
* @return 此Session的剩余存活时间 (单位: )
*/
public long getTimeout() {
public long timeout() {
return SaManager.getSaTokenDao().getSessionTimeout(this.id);
}
@ -411,7 +411,7 @@ public class SaSession implements SaSetValueInterface, Serializable {
*/
public void updateMinTimeout(long minTimeout) {
long min = trans(minTimeout);
long curr = trans(getTimeout());
long curr = trans(timeout());
if(curr < min) {
updateTimeout(minTimeout);
}
@ -423,7 +423,7 @@ public class SaSession implements SaSetValueInterface, Serializable {
*/
public void updateMaxTimeout(long maxTimeout) {
long max = trans(maxTimeout);
long curr = trans(getTimeout());
long curr = trans(timeout());
if(curr > max) {
updateTimeout(maxTimeout);
}

View File

@ -54,13 +54,6 @@
<version>${sa-token.version}</version>
</dependency> -->
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>

View File

@ -18,7 +18,7 @@ public class Test2Controller {
public SaResult test2() {
StpUtil.login(30003);
System.out.println(StpUtil.getSession().getTimeout());
System.out.println(StpUtil.getSession().timeout());
System.out.println(StpUtil.getStpLogic().getTokenSession(false));
return SaResult.ok();

View File

@ -19,9 +19,10 @@
<!-- 所有子模块 -->
<modules>
<module>sa-token-jackson</module>
<module>sa-token-redis</module>
<module>sa-token-redis-template</module>
<module>sa-token-redis-template-jdk-serializer</module>
<module>sa-token-redis-jackson</module>
<module>sa-token-redis-fastjson</module>
<module>sa-token-redis-fastjson2</module>
<module>sa-token-redisson-jackson</module>

View File

@ -20,7 +20,7 @@
<!-- Sa-Token Redis Dependency -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis</artifactId>
<artifactId>sa-token-redis-template</artifactId>
<optional>true</optional>
</dependency>
<dependency>

View File

@ -15,7 +15,11 @@
*/
package cn.dev33.satoken.dao.alone;
import cn.dev33.satoken.dao.*;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
import cn.dev33.satoken.dao.SaTokenDaoRedisFastjson;
import cn.dev33.satoken.dao.SaTokenDaoRedisFastjson2;
import cn.dev33.satoken.dao.impl.SaTokenDaoForRedisTemplate;
import cn.dev33.satoken.exception.SaTokenException;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
@ -210,22 +214,22 @@ public class SaAloneRedisInject implements EnvironmentAware{
// 如果开发者引入的是sa-token-redis
try {
Class.forName("cn.dev33.satoken.dao.SaTokenDaoRedis");
SaTokenDaoRedis dao = (SaTokenDaoRedis)saTokenDao;
dao.isInit = false;
dao.init(factory);
return;
} catch (ClassNotFoundException ignored) {
}
// 如果开发者引入的是sa-token-redis-jackson
try {
Class.forName("cn.dev33.satoken.dao.SaTokenDaoRedisJackson");
SaTokenDaoRedisJackson dao = (SaTokenDaoRedisJackson)saTokenDao;
Class.forName("cn.dev33.satoken.dao.SaTokenDaoForRedisTemplate");
SaTokenDaoForRedisTemplate dao = (SaTokenDaoForRedisTemplate)saTokenDao;
dao.isInit = false;
dao.init(factory);
return;
} catch (ClassNotFoundException ignored) {
}
// TODO: 如果开发者引入的是sa-token-redis-jdk-serializer
// try {
// Class.forName("cn.dev33.satoken.dao.SaTokenDaoForRedisTemplate");
// SaTokenDaoRedisJackson dao = (SaTokenDaoRedisJackson)saTokenDao;
// dao.isInit = false;
// dao.init(factory);
// return;
// } catch (ClassNotFoundException ignored) {
// }
// 如果开发者引入的是sa-token-redis-fastjson
try {
Class.forName("cn.dev33.satoken.dao.SaTokenDaoRedisFastjson");

View File

@ -84,8 +84,8 @@ public class SaSessionForFastjsonCustomized extends SaSession {
*/
@Override
@JSONField(serialize = false)
public long getTimeout() {
return super.getTimeout();
public long timeout() {
return super.timeout();
}
}

View File

@ -84,8 +84,8 @@ public class SaSessionForFastjson2Customized extends SaSession {
*/
@Override
@JSONField(serialize = false)
public long getTimeout() {
return super.getTimeout();
public long timeout() {
return super.timeout();
}
}

View File

@ -17,30 +17,14 @@
<description>sa-token integrate redis (to jackson)</description>
<dependencies>
<!-- sa-token-spring-boot-starter -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId>
</dependency>
<!-- RedisTemplate 相关操作API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jackson</artifactId>
</dependency>
<!-- jackson-datatype-jsr310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<optional>true</optional>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-template</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,48 +0,0 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import cn.dev33.satoken.session.SaSession;
/**
* Jackson 定制版 SaSession忽略 timeout 等属性的序列化
*
* @author click33
* @since 1.34.0
*/
@JsonIgnoreProperties({"timeout"})
public class SaSessionForJacksonCustomized extends SaSession {
/**
*
*/
private static final long serialVersionUID = -7600983549653130681L;
public SaSessionForJacksonCustomized() {
super();
}
/**
* 构建一个Session对象
* @param id Session的id
*/
public SaSessionForJacksonCustomized(String id) {
super(id);
}
}

View File

@ -0,0 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-plugin</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>
<name>sa-token-redis-jdk-serializer</name>
<artifactId>sa-token-redis-template-jdk-serializer</artifactId>
<description>sa-token integrate RedisTemplate jdk-serializer</description>
<dependencies>
<!-- sa-token-spring-boot-starter -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId>
</dependency>
<!-- RedisTemplate 相关操作API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -12,9 +12,9 @@
</parent>
<packaging>jar</packaging>
<name>sa-token-redis</name>
<artifactId>sa-token-redis</artifactId>
<description>sa-token integrate redis</description>
<name>sa-token-redis-template</name>
<artifactId>sa-token-redis-template</artifactId>
<description>sa-token integrate RedisTemplate</description>
<dependencies>
<!-- sa-token-spring-boot-starter -->

View File

@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao;
package cn.dev33.satoken.dao.impl;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.util.SaFoxUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
@ -28,21 +28,18 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Sa-Token 持久层实现 [ Redis存储Jackson序列化 ]
* Sa-Token 持久层实现 [ Redis 存储 ] (可用环境: SpringBoot2SpringBoot3)
*
* @author click33
* @since 1.34.0
*/
@Component
public class SaTokenDaoRedisJackson implements SaTokenDao {
public class SaTokenDaoForRedisTemplate implements SaTokenDao {
public StringRedisTemplate stringRedisTemplate;
/**
* String 读写专用
*/
public StringRedisTemplate stringRedisTemplate;
/**
* 标记是否已初始化成功
* 标记当前 redis 连接信息是否已初始化成功
*/
public boolean isInit;
@ -59,9 +56,6 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
stringTemplate.afterPropertiesSet();
this.stringRedisTemplate = stringTemplate;
// 重写 SaSession 生成策略
SaStrategy.instance.createSession = (sessionId) -> new SaSessionForJacksonCustomized(sessionId);
// 打上标记表示已经初始化成功后续无需再重新初始化
this.isInit = true;
}
@ -76,7 +70,7 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
}
/**
* 写入Value并设定存活时间 (单位: )
* 写入Value并设定存活时间 (单位: )
*/
@Override
public void set(String key, String value, long timeout) {
@ -92,7 +86,7 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
}
/**
* 改指定key-value键值对 (过期时间不变)
* 改指定key-value键值对 (过期时间不变)
*/
@Override
public void update(String key, String value) {
@ -139,6 +133,7 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 搜索数据
@ -150,4 +145,5 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
return SaFoxUtil.searchList(list, start, size, sortType);
}
}

View File

@ -1 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.SaTokenDaoRedisJackson
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.impl.SaTokenDaoForRedisTemplate

View File

@ -0,0 +1 @@
cn.dev33.satoken.dao.impl.SaTokenDaoForRedisTemplate

View File

@ -82,8 +82,8 @@ public class SaSessionForJson extends SaSession {
* 忽略 timeout 字段的序列化
*/
@Override
public long getTimeout() {
return super.getTimeout();
public long timeout() {
return super.timeout();
}
}

View File

@ -201,7 +201,7 @@ public class SaSsoClientTemplate extends SaSsoTemplate {
*/
public SaResult request(String url) {
String body = getClientConfig().sendHttp.apply(url);
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(body);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(body);
return new SaResult(map);
}

View File

@ -29,6 +29,7 @@ import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.log.SaLog;
import cn.dev33.satoken.plugin.SaTokenPluginLoader;
import cn.dev33.satoken.same.SaSameTemplate;
import cn.dev33.satoken.sign.SaSignTemplate;
import cn.dev33.satoken.spring.pathmatch.SaPathMatcherHolder;
@ -68,6 +69,8 @@ public class SaBeanInject {
if(saTokenConfig != null) {
SaManager.setConfig(saTokenConfig);
}
// 初始化 Sa-Token SPI 插件
SaTokenPluginLoader.init();
}
/**

View File

@ -94,16 +94,16 @@ public class SaSessionTest {
SaSession session = new SaSession("session-1005");
SaManager.getSaTokenDao().setSession(session, 20000);
session.updateMaxTimeout(100);
Assertions.assertTrue(session.getTimeout() <= 100);
System.out.println(session.getTimeout());
Assertions.assertTrue(session.timeout() <= 100);
System.out.println(session.timeout());
// 仍然是 <=100
session.updateMaxTimeout(1000);
Assertions.assertTrue(session.getTimeout() <= 100);
System.out.println(session.getTimeout());
Assertions.assertTrue(session.timeout() <= 100);
System.out.println(session.timeout());
// Min 修改
session.updateMinTimeout(-1);
System.out.println(session.getTimeout());
Assertions.assertTrue(session.getTimeout() == -1);
System.out.println(session.timeout());
Assertions.assertTrue(session.timeout() == -1);
}
// 测试token 签名