From 20f6bd7b3ddfe032008f7954252f1b1da0ad6696 Mon Sep 17 00:00:00 2001 From: shengzhang <2393584716@qq.com> Date: Sun, 27 Dec 2020 18:18:08 +0800 Subject: [PATCH] =?UTF-8?q?dao=E5=B1=82=E9=BB=98=E8=AE=A4=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=A2=9E=E5=8A=A0=E5=AE=9A=E6=97=B6=E6=B8=85=E7=90=86?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E6=95=B0=E6=8D=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/dev33/satoken/SaTokenManager.java | 3 + .../dev33/satoken/config/SaTokenConfig.java | 28 ++++++-- .../satoken/dao/SaTokenDaoDefaultImpl.java | 72 +++++++++++++++++-- .../cn/dev33/satoken/util/SaTaskUtil.java | 57 +++++++++++++++ sa-token-demo-springboot/pom.xml | 4 +- .../java/com/pj/SaTokenDemoApplication.java | 1 - sa-token-doc/doc/use/config.md | 1 + 7 files changed, 153 insertions(+), 13 deletions(-) create mode 100644 sa-token-core/src/main/java/cn/dev33/satoken/util/SaTaskUtil.java diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java b/sa-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java index 06c962c5..53e1665f 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java @@ -55,6 +55,9 @@ public class SaTokenManager { return saTokenDao; } public static void setSaTokenDao(SaTokenDao saTokenDao) { + if(SaTokenManager.saTokenDao != null && (SaTokenManager.saTokenDao instanceof SaTokenDaoDefaultImpl)) { + ((SaTokenDaoDefaultImpl)SaTokenManager.saTokenDao).endRefreshTimer(); + } SaTokenManager.saTokenDao = saTokenDao; } public synchronized static void initSaTokenDao() { diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java index c0278f3d..eb4317f8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java @@ -46,6 +46,11 @@ public class SaTokenConfig { * token风格 */ private String tokenStyle = "uuid"; + + /** + * 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 + */ + private int dataRefreshPeriod = 30; /** * 是否在初始化配置时打印版本字符画 @@ -53,8 +58,7 @@ public class SaTokenConfig { private Boolean isV = true; - - + /** * @return tokenName */ @@ -181,7 +185,20 @@ public class SaTokenConfig { this.isV = isV; } - + /** + * @return dataRefreshPeriod + */ + public int getDataRefreshPeriod() { + return dataRefreshPeriod; + } + + /** + * @param dataRefreshPeriod 要设置的 dataRefreshPeriod + */ + public void setDataRefreshPeriod(int dataRefreshPeriod) { + this.dataRefreshPeriod = dataRefreshPeriod; + } + /** * 将对象转为String字符串 @@ -190,8 +207,11 @@ public class SaTokenConfig { public String toString() { return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout + ", isShare=" + isShare + ", isReadBody=" + isReadBody + ", isReadHead=" + isReadHead - + ", isReadCookie=" + isReadCookie + ", tokenStyle=" + tokenStyle + ", isV=" + isV + "]"; + + ", isReadCookie=" + isReadCookie + ", tokenStyle=" + tokenStyle + ", isV=" + isV + + ", dataRefreshPeriod=" + dataRefreshPeriod + "]"; } + + 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 1a7d9344..dad1096e 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 @@ -1,9 +1,15 @@ package cn.dev33.satoken.dao; -import java.util.HashMap; -import java.util.Map; +import java.util.Iterator; +import java.util.Map; +import java.util.Timer; +import java.util.concurrent.ConcurrentHashMap; + +import cn.dev33.satoken.SaTokenManager; import cn.dev33.satoken.session.SaSession; +import cn.dev33.satoken.util.SaTaskUtil; +import cn.dev33.satoken.util.SaTaskUtil.FunctionRunClass; /** * sa-token持久层默认的实现类 , 基于内存Map @@ -11,17 +17,27 @@ import cn.dev33.satoken.session.SaSession; * */ public class SaTokenDaoDefaultImpl implements SaTokenDao { + /** * 所有数据集合 */ - public Map dataMap = new HashMap(); + public Map dataMap = new ConcurrentHashMap(); /** * 过期时间集合 (单位: 毫秒) , 记录所有key的到期时间 [注意不是剩余存活时间] */ - public Map expireMap = new HashMap(); + public Map expireMap = new ConcurrentHashMap(); + /** + * 构造函数 + */ + public SaTokenDaoDefaultImpl() { + initRefreshTimer(); + } + + + // ------------------------ String 读写操作 @Override public String getValue(String key) { @@ -53,7 +69,9 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao { public long getTimeout(String key) { return getKeyTimeout(key); } + + // ------------------------ Session 读写操作 @Override public SaSession getSession(String sessionId) { @@ -87,8 +105,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao { } - - // --------------------- + // ------------------------ Session 读写操作 /** * 如果指定key已经过期,则立即清除它 @@ -131,8 +148,51 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao { } + // --------------------- 定时清理过期数据 + /** + * 定时任务对象 + */ + public Timer refreshTimer; + + /** + * 清理所有已经过期的key + */ + public void refreshDataMap() { + Iterator keys = expireMap.keySet().iterator(); + while (keys.hasNext()) { + clearKeyByTimeout(keys.next()); + } + } + /** + * 初始化定时任务 + */ + public void initRefreshTimer() { + // 如果已经被初始化过了, 则停止它 + if(this.refreshTimer != null) { + this.endRefreshTimer(); + } + + // 开始新的定时任务 + if(SaTokenManager.getConfig().getDataRefreshPeriod() < 0) { + return; + } + int period = SaTokenManager.getConfig().getDataRefreshPeriod() * 1000; + this.refreshTimer = SaTaskUtil.setInterval(new FunctionRunClass() { + @Override + public void run() { + refreshDataMap(); + } + }, period, period); + } + + /** + * 结束定时任务 + */ + public void endRefreshTimer() { + this.refreshTimer.cancel(); + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTaskUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTaskUtil.java new file mode 100644 index 00000000..bb46f91d --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaTaskUtil.java @@ -0,0 +1,57 @@ +package cn.dev33.satoken.util; + +import java.util.Timer; +import java.util.TimerTask; + +/** + * 任务调度Util + * @author kong + * + */ +public class SaTaskUtil { + + /** + * 延时指定毫秒执行一个函数 + * @param fc 要执行的函数 + * @param delay 延时的毫秒数 + * @return timer任务对象 + */ + public static Timer setTimeout(FunctionRunClass fc, int delay) { + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + fc.run(); + timer.cancel(); + } + }, delay); + return timer; + } + + /** + * 延时delay毫秒,每隔period毫秒执行一个函数 + * @param fc 要执行的函数 + * @param delay 延时的毫秒数 + * @param period 每隔多少毫秒执行一次 + * @return timer任务对象 + */ + public static Timer setInterval(FunctionRunClass fc, int delay, int period) { + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + fc.run(); + } + }, delay, period); + return timer; + } + + /** + * 封装一个内部类,便于操作 + * @author kong + */ + public static interface FunctionRunClass{ + public void run(); + } + +} diff --git a/sa-token-demo-springboot/pom.xml b/sa-token-demo-springboot/pom.xml index 37d083c3..03008c76 100644 --- a/sa-token-demo-springboot/pom.xml +++ b/sa-token-demo-springboot/pom.xml @@ -33,11 +33,11 @@ - + diff --git a/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java index 6abf239d..4422fe1d 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java @@ -11,7 +11,6 @@ public class SaTokenDemoApplication { public static void main(String[] args) { SpringApplication.run(SaTokenDemoApplication.class, args); System.out.println("\n启动成功:sa-token配置如下:" + SaTokenManager.getConfig()); - System.out.println(SaTokenManager.getSaTokenDao()); } } \ No newline at end of file diff --git a/sa-token-doc/doc/use/config.md b/sa-token-doc/doc/use/config.md index 9d3527cb..797ac8fb 100644 --- a/sa-token-doc/doc/use/config.md +++ b/sa-token-doc/doc/use/config.md @@ -77,4 +77,5 @@ spring: | isReadHead | Boolean | true | 是否尝试从header里读取token | | isReadCookie | Boolean | true | 是否尝试从cookie里读取token | | tokenStyle | String | uuid | token风格, [参考:花式token](/use/token-style) | +| dataRefreshPeriod | int | 30 | 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 | | isV | Boolean | true | 是否在初始化配置时打印版本字符画 |