diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java b/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java index b6cfc10b..a43c739e 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/SaManager.java @@ -9,6 +9,7 @@ import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.config.SaTokenConfigFactory; import cn.dev33.satoken.context.SaTokenContext; import cn.dev33.satoken.context.SaTokenContextDefaultImpl; +import cn.dev33.satoken.context.second.SaTokenSecondContext; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl; import cn.dev33.satoken.exception.SaTokenException; @@ -18,12 +19,12 @@ import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpInterfaceDefaultImpl; import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; -import cn.dev33.satoken.temp.SaTempInterface; import cn.dev33.satoken.temp.SaTempDefaultImpl; +import cn.dev33.satoken.temp.SaTempInterface; import cn.dev33.satoken.util.SaFoxUtil; /** - * 管理 Sa-Token 所有接口对象 + * 管理 Sa-Token 所有全局组件 * @author kong * */ @@ -111,21 +112,49 @@ public class SaManager { } /** - * 上下文 Bean + * 上下文Context Bean */ private volatile static SaTokenContext saTokenContext; public static void setSaTokenContext(SaTokenContext saTokenContext) { SaManager.saTokenContext = saTokenContext; } public static SaTokenContext getSaTokenContext() { - if (saTokenContext == null) { - synchronized (SaManager.class) { - if (saTokenContext == null) { - setSaTokenContext(new SaTokenContextDefaultImpl()); - } + return saTokenContext; + } + + /** + * 二级Context + */ + private volatile static SaTokenSecondContext saTokenSecondContext; + public static SaTokenSecondContext getSaTokenSecondContext() { + return saTokenSecondContext; + } + public static void setSaTokenSecondContext(SaTokenSecondContext saTokenSecondContext) { + SaManager.saTokenSecondContext = saTokenSecondContext; + } + + /** + * 获取一个可用的SaTokenContext + * @return / + */ + public static SaTokenContext getSaTokenContextOrSecond() { + + // s1. 一级Context可用时返回一级Context + if(saTokenContext != null) { + if(saTokenSecondContext == null || saTokenContext.isValid()) { + // 因为 isValid 是一个耗时操作,所以此处假定:二级Context为null的情况下无需验证一级Context有效性 + // 这样可以提升6倍左右的上下文获取速度 + return saTokenContext; } } - return saTokenContext; + + // s2. 一级Context不可用时判断二级Context是否可用 + if(saTokenSecondContext != null && saTokenSecondContext.isValid()) { + return saTokenSecondContext; + } + + // s3. 都不行,就返回默认的 Context + return SaTokenContextDefaultImpl.defaultContext; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaHolder.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaHolder.java index 10d53772..b6834e34 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaHolder.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaHolder.java @@ -11,6 +11,15 @@ import cn.dev33.satoken.context.model.SaStorage; * */ public class SaHolder { + + /** + * 获取当前请求的 SaTokenContext + * + * @return see note + */ + public static SaTokenContext getContext() { + return SaManager.getSaTokenContextOrSecond(); + } /** * 获取当前请求的 [Request] 对象 @@ -18,7 +27,7 @@ public class SaHolder { * @return see note */ public static SaRequest getRequest() { - return SaManager.getSaTokenContext().getRequest(); + return SaManager.getSaTokenContextOrSecond().getRequest(); } /** @@ -27,7 +36,7 @@ public class SaHolder { * @return see note */ public static SaResponse getResponse() { - return SaManager.getSaTokenContext().getResponse(); + return SaManager.getSaTokenContextOrSecond().getResponse(); } /** @@ -36,7 +45,7 @@ public class SaHolder { * @return see note */ public static SaStorage getStorage() { - return SaManager.getSaTokenContext().getStorage(); + return SaManager.getSaTokenContextOrSecond().getStorage(); } } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContext.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContext.java index 2d4ec90b..c1edfae0 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContext.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContext.java @@ -41,4 +41,12 @@ public interface SaTokenContext { */ public boolean matchPath(String pattern, String path); + /** + * 此上下文是否有效 + * @return / + */ + public default boolean isValid() { + return false; + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextDefaultImpl.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextDefaultImpl.java index d3f10178..0fb743b9 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextDefaultImpl.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextDefaultImpl.java @@ -17,6 +17,11 @@ import cn.dev33.satoken.exception.SaTokenException; * */ public class SaTokenContextDefaultImpl implements SaTokenContext { + + /** + * 默认的上下文处理器对象 + */ + public static SaTokenContextDefaultImpl defaultContext = new SaTokenContextDefaultImpl(); /** * 默认的错误提示语 @@ -56,5 +61,4 @@ public class SaTokenContextDefaultImpl implements SaTokenContext { } - } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextForThreadLocal.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextForThreadLocal.java index a2c75b6e..e2c637f8 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextForThreadLocal.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/SaTokenContextForThreadLocal.java @@ -37,4 +37,9 @@ public class SaTokenContextForThreadLocal implements SaTokenContext { return false; } + @Override + public boolean isValid() { + return SaTokenContextForThreadLocalStorage.getBox() != null; + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContext.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContext.java new file mode 100644 index 00000000..f1047e1b --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContext.java @@ -0,0 +1,15 @@ +package cn.dev33.satoken.context.second; + +import cn.dev33.satoken.context.SaTokenContext; + +/** + * Sa-Token 二级Context - 基础接口 + * + *
(利用继承机制实现区别 [一级Context] 与 [二级Context] 的目的) + * + * @author kong + * + */ +public interface SaTokenSecondContext extends SaTokenContext { + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContextCreator.java b/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContextCreator.java new file mode 100644 index 00000000..005afaf3 --- /dev/null +++ b/sa-token-core/src/main/java/cn/dev33/satoken/context/second/SaTokenSecondContextCreator.java @@ -0,0 +1,18 @@ +package cn.dev33.satoken.context.second; + +/** + * Sa-Token 二级Context - 创建器 + * + * @author kong + * + */ +@FunctionalInterface +public interface SaTokenSecondContextCreator { + + /** + * 创建一个二级 Context + * @return / + */ + public SaTokenSecondContext create(); + +} diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java index cde5ea38..af4f4a23 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouter.java @@ -26,7 +26,7 @@ public class SaRouter { * @return 是否匹配成功 */ public static boolean isMatch(String pattern, String path) { - return SaManager.getSaTokenContext().matchPath(pattern, path); + return SaManager.getSaTokenContextOrSecond().matchPath(pattern, path); } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouterUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouterUtil.java index dd1e4a1b..ce199a61 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouterUtil.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/router/SaRouterUtil.java @@ -27,7 +27,7 @@ public class SaRouterUtil { * @return 是否匹配成功 */ public static boolean isMatch(String pattern, String path) { - return SaManager.getSaTokenContext().matchPath(pattern, path); + return SaManager.getSaTokenContextOrSecond().matchPath(pattern, path); } /** diff --git a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java index 3da66ead..2cecf14a 100644 --- a/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java +++ b/sa-token-demo/sa-token-demo-springboot/src/main/java/com/pj/SaTokenDemoApplication.java @@ -14,8 +14,8 @@ import cn.dev33.satoken.SaManager; public class SaTokenDemoApplication { public static void main(String[] args) { - SpringApplication.run(SaTokenDemoApplication.class, args); - System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); + SpringApplication.run(SaTokenDemoApplication.class, args); + System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig()); } } diff --git a/sa-token-doc/doc/more/sa-token-donate.md b/sa-token-doc/doc/more/sa-token-donate.md index 5e8e0f06..9e434118 100644 --- a/sa-token-doc/doc/more/sa-token-donate.md +++ b/sa-token-doc/doc/more/sa-token-donate.md @@ -17,25 +17,25 @@ Sa-Token 采用 Apache-2.0 开源协议,**承诺框架本身与官网文档永
-| 赞助人 | 赞助金额 | 留言 | -| :-------- | :-------- | :-------- | -| apifox001 | ¥ 200 | 开源不易,Apifox(apifox.cn)和你们一起加油! | -| 永夜 | ¥ 20 | 感谢您的开源项目! | -| 苏永晓 | ¥ 10 | 感谢您的开源项目! | -| xiaoyan | ¥ 200 | 好的作者理应被认可 | -| xiaoyan | ¥ 50 | be better | -| 孔孔的空空 | ¥ 500 | 感谢您的开源项目! | -| Wizzer | ¥ 20 | 感谢您的开源项目! | -| 二范先生 | ¥ 20 | 省长加油啊 喝杯茶 | -| EchoSlammaJamma | ¥ 20 | 感谢您的开源项目! | -| xue1992wz | ¥ 20 | 感谢您的开源项目! | -| whcrow | ¥ 20 | 军师加油! | -| njx33 | ¥ 10 | 感谢您的开源项目! | -| zhangjiaxiaozhuo | ¥ 10 | 感谢您的开源项目! | -| 知知 | ¥ 10 | 感谢您的开源项目! | -| 省长 | ¥ 10 | java中最好用的权限认证框架! | +| 赞助人 | 赞助金额 | 留言 | 时间 | +| :-------- | :-------- | :-------- | :-------- | +| apifox001 | ¥ 200 | 开源不易,Apifox(apifox.cn)和你们一起加油! | 2021-10-15 | +| 永夜 | ¥ 20 | 感谢您的开源项目! | 2021-09-18 | +| 苏永晓 | ¥ 10 | 感谢您的开源项目! | 2021-09-01 | +| xiaoyan | ¥ 200 | 好的作者理应被认可 | 2021-08-24 | +| xiaoyan | ¥ 50 | be better | 2021-07-31 | +| 孔孔的空空 | ¥ 500 | 感谢您的开源项目! | 2021-07-30 | +| Wizzer | ¥ 20 | 感谢您的开源项目! | 2021-05-22 | +| 二范先生 | ¥ 20 | 省长加油啊 喝杯茶 | 2021-03-16 | +| EchoSlammaJamma | ¥ 20 | 感谢您的开源项目! | 2021-03-16 | +| xue1992wz | ¥ 20 | 感谢您的开源项目! | 2021-03-16 | +| whcrow | ¥ 20 | 军师加油! | 2021-03-16 | +| njx33 | ¥ 10 | 感谢您的开源项目! | 2020-12-17 | +| zhangjiaxiaozhuo | ¥ 10 | 感谢您的开源项目! | 2020-12-15 | +| 知知 | ¥ 10 | 感谢您的开源项目! | 2020-12-15 | +| 省长 | ¥ 10 | java中最好用的权限认证框架! | 2020-12-15 | -感谢每一位小伙伴的支持! +感谢每一位小伙伴的热心支持! diff --git a/sa-token-doc/doc/plugin/jwt-extend.md b/sa-token-doc/doc/plugin/jwt-extend.md index 6c9464bf..fcd98b1f 100644 --- a/sa-token-doc/doc/plugin/jwt-extend.md +++ b/sa-token-doc/doc/plugin/jwt-extend.md @@ -8,7 +8,7 @@ 首先在项目已经引入 Sa-Token 的基础上,继续添加: ``` xml - +