From 9095ea3851d20b97a00eba749fc8ea27e75b54d1 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Sat, 8 Mar 2025 20:25:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20sa-token-caffeine?= =?UTF-8?q?=20=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mvn clean.bat | 1 + .../satoken/dao/SaTokenDaoDefaultImpl.java | 10 +- .../dev33/satoken/dao/map/SaMapPackage.java | 63 +++++++++++ .../map/SaMapPackageForConcurrentHashMap.java | 56 ++++++++++ .../satoken/dao/timedcache/SaTimedCache.java | 17 ++- sa-token-demo/pom.xml | 1 + sa-token-demo/sa-token-demo-caffeine/pom.xml | 59 ++++++++++ .../java/com/pj/SaTokenDemoApplication.java | 21 ++++ .../java/com/pj/current/GlobalException.java | 20 ++++ .../java/com/pj/test/LoginController.java | 48 +++++++++ .../src/main/resources/application.yml | 23 ++++ sa-token-dependencies/pom.xml | 8 ++ sa-token-doc/plugin/dao-extend.md | 14 +-- sa-token-doc/start/download.md | 2 + sa-token-plugin/pom.xml | 1 + sa-token-plugin/sa-token-caffeine/pom.xml | 30 ++++++ .../satoken/dao/SaMapPackageForCaffeine.java | 82 ++++++++++++++ .../satoken/dao/SaTokenDaoForCaffeine.java | 102 ++++++++++++++++++ .../plugin/SaTokenPluginForCaffeine.java | 36 +++++++ .../cn.dev33.satoken.plugin.SaTokenPlugin | 1 + 20 files changed, 581 insertions(+), 14 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackage.java create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackageForConcurrentHashMap.java create mode 100644 sa-token-demo/sa-token-demo-caffeine/pom.xml create mode 100644 sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/SaTokenDemoApplication.java create mode 100644 sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/current/GlobalException.java create mode 100644 sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/test/LoginController.java create mode 100644 sa-token-demo/sa-token-demo-caffeine/src/main/resources/application.yml create mode 100644 sa-token-plugin/sa-token-caffeine/pom.xml create mode 100644 sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaMapPackageForCaffeine.java create mode 100644 sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaTokenDaoForCaffeine.java create mode 100644 sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForCaffeine.java create mode 100644 sa-token-plugin/sa-token-caffeine/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/mvn clean.bat b/mvn clean.bat index c15702f3..f263dc6f 100644 --- a/mvn clean.bat +++ b/mvn clean.bat @@ -14,6 +14,7 @@ cd sa-token-demo-case & call mvn clean & cd .. cd sa-token-demo-device-lock & call mvn clean & cd .. cd sa-token-demo-grpc & call mvn clean & cd .. cd sa-token-demo-hutool-timed-cache & call mvn clean & cd .. +cd sa-token-demo-caffeine & call mvn clean & cd .. cd sa-token-demo-jwt & call mvn clean & cd .. cd sa-token-demo-quick-login & call mvn clean & cd .. cd sa-token-demo-solon & call mvn clean & cd .. diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java index f90d8a93..c045b32b 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java @@ -17,20 +17,24 @@ package cn.dev33.satoken.dao; import cn.dev33.satoken.dao.auto.SaTokenDaoByStringFollowObject; +import cn.dev33.satoken.dao.map.SaMapPackageForConcurrentHashMap; import cn.dev33.satoken.dao.timedcache.SaTimedCache; import cn.dev33.satoken.util.SaFoxUtil; import java.util.List; /** - * Sa-Token 持久层接口,默认实现类,基于 SaTimedCache (内存 Map,系统重启后数据丢失) + * Sa-Token 持久层接口,默认实现类,基于 SaTimedCache - ConcurrentHashMap (内存缓存,系统重启后数据丢失) * * @author click33 * @since 1.10.0 */ public class SaTokenDaoDefaultImpl implements SaTokenDaoByStringFollowObject { - public SaTimedCache timedCache = new SaTimedCache(); + public SaTimedCache timedCache = new SaTimedCache( + new SaMapPackageForConcurrentHashMap<>(), + new SaMapPackageForConcurrentHashMap<>() + ); // ------------------------ Object 读写操作 @@ -75,7 +79,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDaoByStringFollowObject { @Override public List searchData(String prefix, String keyword, int start, int size, boolean sortType) { - return SaFoxUtil.searchList(timedCache.expireMap.keySet(), prefix, keyword, start, size, sortType); + return SaFoxUtil.searchList(timedCache.keySet(), prefix, keyword, start, size, sortType); } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackage.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackage.java new file mode 100644 index 00000000..e0294c41 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackage.java @@ -0,0 +1,63 @@ +/* + * 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.map; + +import java.util.Set; + +/** + * Map 包装类 + * + * @author click33 + * @since 1.41.0 + */ +public interface SaMapPackage { + + /** + * 获取底层被包装的源对象 + * + * @return / + */ + Object getSource(); + + + /** + * 读 + * + * @param key / + * @return / + */ + V get(String key); + + /** + * 写 + * + * @param key / + * @param value / + */ + void put(String key, V value); + + /** + * 删 + * @param key / + */ + void remove(String key); + + /** + * 所有 key + */ + Set keySet(); + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackageForConcurrentHashMap.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackageForConcurrentHashMap.java new file mode 100644 index 00000000..fd7e696b --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/map/SaMapPackageForConcurrentHashMap.java @@ -0,0 +1,56 @@ +/* + * 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.map; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Map 包装类 (ConcurrentHashMap 版) + * + * @author click33 + * @since 1.41.0 + */ +public class SaMapPackageForConcurrentHashMap implements SaMapPackage { + + private final ConcurrentHashMap map = new ConcurrentHashMap(); + + @Override + public Object getSource() { + return map; + } + + @Override + public V get(String key) { + return map.get(key); + } + + @Override + public void put(String key, V value) { + map.put(key, value); + } + + @Override + public void remove(String key) { + map.remove(key); + } + + @Override + public Set keySet() { + return map.keySet(); + } + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/timedcache/SaTimedCache.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/timedcache/SaTimedCache.java index fcdb5c40..9ec0be15 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/timedcache/SaTimedCache.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/timedcache/SaTimedCache.java @@ -18,9 +18,9 @@ package cn.dev33.satoken.dao.timedcache; import cn.dev33.satoken.SaManager; import cn.dev33.satoken.dao.SaTokenDao; +import cn.dev33.satoken.dao.map.SaMapPackage; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; /** * 一个定时缓存的简单实现,采用:惰性检查 + 异步循环扫描 @@ -33,12 +33,17 @@ public class SaTimedCache { /** * 存储数据的集合 */ - public Map dataMap = new ConcurrentHashMap<>(); + public SaMapPackage dataMap; /** * 存储数据过期时间的集合(单位: 毫秒), 记录所有 key 的到期时间 (注意存储的是到期时间,不是剩余存活时间) */ - public Map expireMap = new ConcurrentHashMap<>(); + public SaMapPackage expireMap; + + public SaTimedCache(SaMapPackage dataMap, SaMapPackage expireMap) { + this.dataMap = dataMap; + this.expireMap = expireMap; + } // ------------------------ 基础 API 读写操作 @@ -76,6 +81,10 @@ public class SaTimedCache { expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000)); } + public Set keySet() { + return dataMap.keySet(); + } + // --------- 过期时间相关操作 diff --git a/sa-token-demo/pom.xml b/sa-token-demo/pom.xml index 27585b8a..a452341e 100644 --- a/sa-token-demo/pom.xml +++ b/sa-token-demo/pom.xml @@ -13,6 +13,7 @@ sa-token-demo-alone-redis-cluster sa-token-demo-beetl sa-token-demo-bom-import + sa-token-demo-caffeine sa-token-demo-case sa-token-demo-device-lock sa-token-demo-dubbo/sa-token-demo-dubbo-provider diff --git a/sa-token-demo/sa-token-demo-caffeine/pom.xml b/sa-token-demo/sa-token-demo-caffeine/pom.xml new file mode 100644 index 00000000..b16941f5 --- /dev/null +++ b/sa-token-demo/sa-token-demo-caffeine/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + cn.dev33 + sa-token-demo-caffeine + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.5.14 + + + + + + + 1.40.0 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + + + cn.dev33 + sa-token-spring-boot-starter + ${sa-token.version} + + + + + cn.dev33 + sa-token-caffeine + ${sa-token.version} + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + \ No newline at end of file diff --git a/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/SaTokenDemoApplication.java new file mode 100644 index 00000000..105a522d --- /dev/null +++ b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/SaTokenDemoApplication.java @@ -0,0 +1,21 @@ +package com.pj; + +import cn.dev33.satoken.SaManager; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Sa-Token 整合 Caffeine 示例 + * @author click33 + * + */ +@SpringBootApplication +public class SaTokenDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(SaTokenDemoApplication.class, args); + System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); + System.out.println(SaManager.getSaTokenDao()); + } + +} diff --git a/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/current/GlobalException.java b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/current/GlobalException.java new file mode 100644 index 00000000..750fc780 --- /dev/null +++ b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/current/GlobalException.java @@ -0,0 +1,20 @@ +package com.pj.current; + +import cn.dev33.satoken.util.SaResult; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理 + */ +@RestControllerAdvice +public class GlobalException { + + // 全局异常拦截(拦截项目中的所有异常) + @ExceptionHandler + public SaResult handlerException(Exception e) { + e.printStackTrace(); + return SaResult.error(e.getMessage()); + } + +} diff --git a/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/test/LoginController.java b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/test/LoginController.java new file mode 100644 index 00000000..34eea9a1 --- /dev/null +++ b/sa-token-demo/sa-token-demo-caffeine/src/main/java/com/pj/test/LoginController.java @@ -0,0 +1,48 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; + +/** + * 登录测试 + * @author click33 + * + */ +@RestController +@RequestMapping("/acc/") +public class LoginController { + + // 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456 + @RequestMapping("doLogin") + public SaResult doLogin(String name, String pwd) { + // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 + if("zhang".equals(name) && "123456".equals(pwd)) { + StpUtil.login(10001); + return SaResult.ok("登录成功"); + } + return SaResult.error("登录失败"); + } + + // 查询登录状态 ---- http://localhost:8081/acc/isLogin + @RequestMapping("isLogin") + public SaResult isLogin() { + return SaResult.ok("是否登录:" + StpUtil.isLogin()); + } + + // 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo + @RequestMapping("tokenInfo") + public SaResult tokenInfo() { + return SaResult.data(StpUtil.getTokenInfo()); + } + + // 测试注销 ---- http://localhost:8081/acc/logout + @RequestMapping("logout") + public SaResult logout() { + StpUtil.logout(); + return SaResult.ok(); + } + +} diff --git a/sa-token-demo/sa-token-demo-caffeine/src/main/resources/application.yml b/sa-token-demo/sa-token-demo-caffeine/src/main/resources/application.yml new file mode 100644 index 00000000..89ed4471 --- /dev/null +++ b/sa-token-demo/sa-token-demo-caffeine/src/main/resources/application.yml @@ -0,0 +1,23 @@ +# 端口 +server: + port: 8081 + +# sa-token 配置 +sa-token: + # token 名称 (同时也是 cookie 名称) + token-name: satoken + # token 有效期(单位:秒) 默认30天,-1 代表永久有效 + timeout: 2592000 + # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 + active-timeout: -1 + # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) + is-share: true + # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) + token-style: uuid + # 是否输出操作日志 + is-log: true + + + \ No newline at end of file diff --git a/sa-token-dependencies/pom.xml b/sa-token-dependencies/pom.xml index 728ce526..4f934e4e 100644 --- a/sa-token-dependencies/pom.xml +++ b/sa-token-dependencies/pom.xml @@ -38,6 +38,7 @@ 2.0.15 3.45.0 5.8.36 + 3.2.0 @@ -265,6 +266,13 @@ ${hutool-cache.version} + + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + + cn.dev33 diff --git a/sa-token-doc/plugin/dao-extend.md b/sa-token-doc/plugin/dao-extend.md index 47bd78c3..39650a9f 100644 --- a/sa-token-doc/plugin/dao-extend.md +++ b/sa-token-doc/plugin/dao-extend.md @@ -7,14 +7,14 @@ 框架已提供的集成包包括: - 默认方式:储存在内存中,位于core核心包。 -- sa-token-redis:Redis集成包,使用 jdk 默认序列化方式。 -- sa-token-redis-jackson:Redis集成包,使用 jackson 序列化方式。 -- sa-token-redisx:Redisx 集成包。 -- sa-token-redis-fastjson:Redis集成包,使用 fastjson 序列化方式。 -- sa-token-redis-fastjson2:Redis集成包,使用 fastjson2 序列化方式。 -- sa-token-redisson-jackson:Redis集成包,Redisson客户端使用,jackson 序列化方式。 -- sa-token-redisson-jackson2:通用 redisson 集成方案 (spring, solon, jfinal 等都可用)。 +- sa-token-redis-template:Redis Template 集成包。 +- sa-token-redis-template-jdk-serializer:Redis 集成包,使用 jdk 默认序列化方式。 - sa-token-hutool-timed-cache:集成 hutool 框架的 Timed-Cache 缓存方案(基于内存)。 +- sa-token-caffeine:集成 Caffeine 缓存方案(基于内存)。 +- sa-token-redisson:集成 Redisson 客户端。 +- sa-token-redisson-spring-boot-starter:集成 Redisson 客户端 - SpringBoot 自动配置包 。 +- sa-token-redisx:Redisx 集成包。 + 有关 Redis 集成,详细参考:[集成Redis](/up/integ-redis),更多存储方式欢迎提交PR diff --git a/sa-token-doc/start/download.md b/sa-token-doc/start/download.md index 1ba8060f..99b1bd08 100644 --- a/sa-token-doc/start/download.md +++ b/sa-token-doc/start/download.md @@ -191,6 +191,7 @@ Maven依赖一直无法加载成功?[参考解决方案](https://sa-token.cc/d ├── sa-token-fastjson2 // [插件] Sa-Token 整合 Fastjson (json序列化插件) ├── sa-token-snack3 // [插件] Sa-Token 整合 Snack3 (json序列化插件) ├── sa-token-hutool-timed-cache // [插件] Sa-Token 整合 Hutool 缓存组件 Timed-Cache(基于内存) (数据缓存插件) + ├── sa-token-caffeine // [插件] Sa-Token 整合 Caffeine 缓存组件(基于内存) (数据缓存插件) ├── sa-token-thymeleaf // [插件] Sa-Token 整合 Thymeleaf (自定义标签方言) ├── sa-token-freemarker // [插件] Sa-Token 整合 Freemarker (自定义标签方言) ├── sa-token-dubbo // [插件] Sa-Token 整合 Dubbo (RPC 调用鉴权、状态传递) @@ -228,6 +229,7 @@ Maven依赖一直无法加载成功?[参考解决方案](https://sa-token.cc/d ├── client // [示例] Sa-Token 集成 grpc 鉴权,client 端 ├── server // [示例] Sa-Token 集成 grpc 鉴权,server 端 ├── sa-token-demo-hutool-timed-cache // [示例] Sa-Token 集成 hutool timed-cache + ├── sa-token-demo-caffeine // [示例] Sa-Token 集成 Caffeine ├── sa-token-demo-jwt // [示例] Sa-Token 集成 jwt 登录认证 ├── sa-token-demo-oauth2 // [示例] Sa-Token 集成 OAuth2.0 ├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客户端) diff --git a/sa-token-plugin/pom.xml b/sa-token-plugin/pom.xml index d3e436bd..79e4fb15 100644 --- a/sa-token-plugin/pom.xml +++ b/sa-token-plugin/pom.xml @@ -24,6 +24,7 @@ sa-token-fastjson2 sa-token-snack3 sa-token-hutool-timed-cache + sa-token-caffeine sa-token-thymeleaf sa-token-freemarker sa-token-dubbo diff --git a/sa-token-plugin/sa-token-caffeine/pom.xml b/sa-token-plugin/sa-token-caffeine/pom.xml new file mode 100644 index 00000000..92f32f67 --- /dev/null +++ b/sa-token-plugin/sa-token-caffeine/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + cn.dev33 + sa-token-plugin + ${revision} + ../pom.xml + + jar + + sa-token-caffeine + sa-token-caffeine + sa-token integrate Caffeine + + + + cn.dev33 + sa-token-core + + + com.github.ben-manes.caffeine + caffeine + + + + diff --git a/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaMapPackageForCaffeine.java b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaMapPackageForCaffeine.java new file mode 100644 index 00000000..9ce8322c --- /dev/null +++ b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaMapPackageForCaffeine.java @@ -0,0 +1,82 @@ +/* + * 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 cn.dev33.satoken.dao.map.SaMapPackage; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * Map 包装类 (Caffeine 版) + * + * @author click33 + * @since 1.41.0 + */ +public class SaMapPackageForCaffeine implements SaMapPackage { + + public Cache cache = Caffeine.newBuilder() + .expireAfterWrite(Long.MAX_VALUE, TimeUnit.SECONDS) + .maximumSize(Integer.MAX_VALUE) + .build(); + + @Override + public Object getSource() { + return cache; + } + + /** + * 读 + * + * @param key / + * @return / + */ + @Override + public V get(String key) { + return cache.getIfPresent(key); + } + + /** + * 写 + * + * @param key / + * @param value / + */ + @Override + public void put(String key, V value) { + cache.put(key, value); + } + + /** + * 删 + * @param key / + */ + @Override + public void remove(String key) { + cache.invalidate(key); + } + + /** + * 所有 key + */ + @Override + public Set keySet() { + return cache.asMap().keySet(); + } + +} diff --git a/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaTokenDaoForCaffeine.java b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaTokenDaoForCaffeine.java new file mode 100644 index 00000000..c2b1a1d1 --- /dev/null +++ b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/dao/SaTokenDaoForCaffeine.java @@ -0,0 +1,102 @@ +/* + * 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 cn.dev33.satoken.dao.auto.SaTokenDaoByStringFollowObject; +import cn.dev33.satoken.dao.timedcache.SaTimedCache; +import cn.dev33.satoken.util.SaFoxUtil; + +import java.util.List; + +/** + * Sa-Token 持久层实现,基于 SaTimedCache - Caffeine (内存缓存,系统重启后数据丢失) + * + * @author click33 + * @since 1.41.0 + */ +public class SaTokenDaoForCaffeine implements SaTokenDaoByStringFollowObject { + + public SaTimedCache timedCache = new SaTimedCache( + new SaMapPackageForCaffeine<>(), + new SaMapPackageForCaffeine<>() + ); + + // ------------------------ Object 读写操作 + + @Override + public Object getObject(String key) { + return timedCache.getObject(key); + } + + @Override + @SuppressWarnings("unchecked") + public T getObject(String key, Class classType){ + return (T) getObject(key); + } + + @Override + public void setObject(String key, Object object, long timeout) { + timedCache.setObject(key, object, timeout); + } + + @Override + public void updateObject(String key, Object object) { + timedCache.updateObject(key, object); + } + + @Override + public void deleteObject(String key) { + timedCache.deleteObject(key); + } + + @Override + public long getObjectTimeout(String key) { + return timedCache.getObjectTimeout(key); + } + + @Override + public void updateObjectTimeout(String key, long timeout) { + timedCache.updateObjectTimeout(key, timeout); + } + + + // --------- 会话管理 + + @Override + public List searchData(String prefix, String keyword, int start, int size, boolean sortType) { + return SaFoxUtil.searchList(timedCache.keySet(), prefix, keyword, start, size, sortType); + } + + + // --------- 组件生命周期 + + /** + * 组件被安装时,开始刷新数据线程 + */ + @Override + public void init() { + timedCache.initRefreshThread(); + } + + /** + * 组件被卸载时,结束定时任务,不再定时清理过期数据 + */ + @Override + public void destroy() { + timedCache.endRefreshThread(); + } +} diff --git a/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForCaffeine.java b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForCaffeine.java new file mode 100644 index 00000000..340d980d --- /dev/null +++ b/sa-token-plugin/sa-token-caffeine/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForCaffeine.java @@ -0,0 +1,36 @@ +/* + * 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.plugin; + +import cn.dev33.satoken.SaManager; +import cn.dev33.satoken.dao.SaTokenDaoForCaffeine; + +/** + * SaToken 插件安装:DAO 扩展 - Caffeine 版 + * + * @author click33 + * @since 1.41.0 + */ +public class SaTokenPluginForCaffeine implements SaTokenPlugin { + + @Override + public void install() { + + SaManager.setSaTokenDao(new SaTokenDaoForCaffeine()); + + } + +} \ No newline at end of file diff --git a/sa-token-plugin/sa-token-caffeine/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-caffeine/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin new file mode 100644 index 00000000..077fa608 --- /dev/null +++ b/sa-token-plugin/sa-token-caffeine/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin @@ -0,0 +1 @@ +cn.dev33.satoken.plugin.SaTokenPluginForCaffeine \ No newline at end of file