mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-05-14 04:42:09 +08:00
refactor: 重构所有 rpc 组件的 SaTokenContext 上下文读写策略 & 删除二级上下文模块
This commit is contained in:
@@ -21,9 +21,7 @@ import cn.dev33.satoken.apikey.loader.SaApiKeyDataLoaderDefaultImpl;
|
||||
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.SaTokenContextForThreadLocal;
|
||||
import cn.dev33.satoken.context.second.SaTokenSecondContext;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
|
||||
import cn.dev33.satoken.error.SaErrorCode;
|
||||
@@ -148,7 +146,7 @@ public class SaManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 一级上下文 SaTokenContextContext
|
||||
* 上下文 SaTokenContext
|
||||
*/
|
||||
private volatile static SaTokenContext saTokenContext;
|
||||
public static void setSaTokenContext(SaTokenContext saTokenContext) {
|
||||
@@ -166,42 +164,6 @@ public class SaManager {
|
||||
return saTokenContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级上下文 SaTokenSecondContext
|
||||
*/
|
||||
private volatile static SaTokenSecondContext saTokenSecondContext;
|
||||
public static void setSaTokenSecondContext(SaTokenSecondContext saTokenSecondContext) {
|
||||
SaManager.saTokenSecondContext = saTokenSecondContext;
|
||||
SaTokenEventCenter.doRegisterComponent("SaTokenSecondContext", saTokenSecondContext);
|
||||
}
|
||||
public static SaTokenSecondContext getSaTokenSecondContext() {
|
||||
return 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;
|
||||
}
|
||||
}
|
||||
|
||||
// s2. 一级Context不可用时判断二级Context是否可用
|
||||
if(saTokenSecondContext != null && saTokenSecondContext.isValid()) {
|
||||
return saTokenSecondContext;
|
||||
}
|
||||
|
||||
// s3. 都不行,就返回默认的 Context
|
||||
return SaTokenContextDefaultImpl.defaultContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 临时 token 认证模块
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package cn.dev33.satoken.context;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
|
||||
/**
|
||||
* Sa-Token 上下文处理器
|
||||
@@ -30,37 +31,59 @@ import cn.dev33.satoken.context.model.SaStorage;
|
||||
public interface SaTokenContext {
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Request 包装对象
|
||||
* 初始化上下文
|
||||
*
|
||||
* @param req /
|
||||
* @param res /
|
||||
* @param stg /
|
||||
*/
|
||||
void setContext(SaRequest req, SaResponse res, SaStorage stg);
|
||||
|
||||
/**
|
||||
* 清除化上下文
|
||||
*/
|
||||
void clearContext();
|
||||
|
||||
/**
|
||||
* 判断当前上下文是否可用
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
boolean isValid();
|
||||
|
||||
/**
|
||||
* 获取 Box 对象
|
||||
*/
|
||||
SaTokenContextModelBox getModelBox();
|
||||
|
||||
/**
|
||||
* 获取当前上下文的 Request 包装对象
|
||||
* @see SaRequest
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
SaRequest getRequest();
|
||||
default SaRequest getRequest() {
|
||||
return getModelBox().getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Response 包装对象
|
||||
* 获取当前上下文的 Response 包装对象
|
||||
* @see SaResponse
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
SaResponse getResponse();
|
||||
default SaResponse getResponse(){
|
||||
return getModelBox().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 Storage 包装对象
|
||||
* 获取当前上下文的 Storage 包装对象
|
||||
* @see SaStorage
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
SaStorage getStorage();
|
||||
|
||||
/**
|
||||
* 判断:在本次请求中,此上下文是否可用。
|
||||
* <p> 例如在部分 rpc 调用时, 一级上下文会返回 false,这时候框架就会选择使用二级上下文来处理请求 </p>
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
default boolean isValid() {
|
||||
return false;
|
||||
default SaStorage getStorage(){
|
||||
return getModelBox().getStorage();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package cn.dev33.satoken.context;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
import cn.dev33.satoken.error.SaErrorCode;
|
||||
import cn.dev33.satoken.exception.SaTokenContextException;
|
||||
|
||||
@@ -44,6 +45,26 @@ public class SaTokenContextDefaultImpl implements SaTokenContext {
|
||||
*/
|
||||
public static final String ERROR_MESSAGE = "未能获取有效的上下文处理器";
|
||||
|
||||
@Override
|
||||
public void setContext(SaRequest req, SaResponse res, SaStorage stg) {
|
||||
throw new SaTokenContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContext() {
|
||||
throw new SaTokenContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
throw new SaTokenContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaTokenContextModelBox getModelBox() {
|
||||
throw new SaTokenContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaRequest getRequest() {
|
||||
throw new SaTokenContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
|
||||
|
||||
@@ -13,20 +13,34 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.dev33.satoken.context.second;
|
||||
package cn.dev33.satoken.context;
|
||||
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
|
||||
/**
|
||||
* Sa-Token 二级Context - 基础接口
|
||||
*
|
||||
* <p> (利用继承机制实现区别 [ 一级Context ] 与 [ 二级Context ] 的目的)
|
||||
*
|
||||
* @see SaTokenContext SaTokenContext 上下文处理器
|
||||
* Sa-Token 上下文处理器次级实现:只读上下文
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.28.0
|
||||
* @since 1.42.0
|
||||
*/
|
||||
public interface SaTokenSecondContext extends SaTokenContext {
|
||||
|
||||
public interface SaTokenContextForReadOnly extends SaTokenContext {
|
||||
|
||||
@Override
|
||||
default void setContext(SaRequest req, SaResponse res, SaStorage stg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void clearContext() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default SaTokenContextModelBox getModelBox() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package cn.dev33.satoken.context;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
|
||||
/**
|
||||
* Sa-Token 上下文处理器 [ ThreadLocal 版本 ]
|
||||
@@ -35,23 +36,23 @@ import cn.dev33.satoken.context.model.SaStorage;
|
||||
public class SaTokenContextForThreadLocal implements SaTokenContext {
|
||||
|
||||
@Override
|
||||
public SaRequest getRequest() {
|
||||
return SaTokenContextForThreadLocalStorage.getRequest();
|
||||
public void setContext(SaRequest req, SaResponse res, SaStorage stg) {
|
||||
SaTokenContextForThreadLocalStaff.setModelBox(req, res, stg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaResponse getResponse() {
|
||||
return SaTokenContextForThreadLocalStorage.getResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaStorage getStorage() {
|
||||
return SaTokenContextForThreadLocalStorage.getStorage();
|
||||
public void clearContext() {
|
||||
SaTokenContextForThreadLocalStaff.clearModelBox();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return SaTokenContextForThreadLocalStorage.getBox() != null;
|
||||
return SaTokenContextForThreadLocalStaff.getModelBoxOrNull() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaTokenContextModelBox getModelBox() {
|
||||
return SaTokenContextForThreadLocalStaff.getModelBox();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package cn.dev33.satoken.context;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.context.model.SaStorage;
|
||||
import cn.dev33.satoken.context.model.SaTokenContextModelBox;
|
||||
import cn.dev33.satoken.error.SaErrorCode;
|
||||
import cn.dev33.satoken.exception.SaTokenContextException;
|
||||
|
||||
@@ -29,12 +30,12 @@ import cn.dev33.satoken.exception.SaTokenContextException;
|
||||
* @author click33
|
||||
* @since 1.16.0
|
||||
*/
|
||||
public class SaTokenContextForThreadLocalStorage {
|
||||
public class SaTokenContextForThreadLocalStaff {
|
||||
|
||||
/**
|
||||
* 基于 ThreadLocal 的 [ Box 存储器 ]
|
||||
*/
|
||||
public static ThreadLocal<Box> boxThreadLocal = new InheritableThreadLocal<>();
|
||||
public static ThreadLocal<SaTokenContextModelBox> modelBoxThreadLocal = new InheritableThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 初始化当前线程的 [ Box 存储器 ]
|
||||
@@ -42,34 +43,34 @@ public class SaTokenContextForThreadLocalStorage {
|
||||
* @param response {@link SaResponse}
|
||||
* @param storage {@link SaStorage}
|
||||
*/
|
||||
public static void setBox(SaRequest request, SaResponse response, SaStorage storage) {
|
||||
Box bok = new Box(request, response, storage);
|
||||
boxThreadLocal.set(bok);
|
||||
public static void setModelBox(SaRequest request, SaResponse response, SaStorage storage) {
|
||||
SaTokenContextModelBox bok = new SaTokenContextModelBox(request, response, storage);
|
||||
modelBoxThreadLocal.set(bok);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前线程的 [ Box 存储器 ]
|
||||
*/
|
||||
public static void clearBox() {
|
||||
boxThreadLocal.remove();
|
||||
public static void clearModelBox() {
|
||||
modelBoxThreadLocal.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前线程的 [ Box 存储器 ]
|
||||
* @return /
|
||||
*/
|
||||
public static Box getBox() {
|
||||
return boxThreadLocal.get();
|
||||
public static SaTokenContextModelBox getModelBoxOrNull() {
|
||||
return modelBoxThreadLocal.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前线程的 [ Box 存储器 ], 如果为空则抛出异常
|
||||
* @return /
|
||||
*/
|
||||
public static Box getBoxNotNull() {
|
||||
Box box = boxThreadLocal.get();
|
||||
public static SaTokenContextModelBox getModelBox() {
|
||||
SaTokenContextModelBox box = modelBoxThreadLocal.get();
|
||||
if(box == null) {
|
||||
throw new SaTokenContextException("未能获取有效的上下文").setCode(SaErrorCode.CODE_10002);
|
||||
throw new SaTokenContextException("SaTokenContext 上下文尚未初始化").setCode(SaErrorCode.CODE_10002);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
@@ -80,7 +81,7 @@ public class SaTokenContextForThreadLocalStorage {
|
||||
* @return /
|
||||
*/
|
||||
public static SaRequest getRequest() {
|
||||
return getBoxNotNull().getRequest();
|
||||
return getModelBox().getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +90,7 @@ public class SaTokenContextForThreadLocalStorage {
|
||||
* @return /
|
||||
*/
|
||||
public static SaResponse getResponse() {
|
||||
return getBoxNotNull().getResponse();
|
||||
return getModelBox().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,59 +99,8 @@ public class SaTokenContextForThreadLocalStorage {
|
||||
* @return /
|
||||
*/
|
||||
public static SaStorage getStorage() {
|
||||
return getBoxNotNull().getStorage();
|
||||
return getModelBox().getStorage();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Box 临时内部类,用于存储 [ SaRequest、SaResponse、SaStorage ] 三个包装对象
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.16.0
|
||||
*/
|
||||
public static class Box {
|
||||
|
||||
public SaRequest request;
|
||||
|
||||
public SaResponse response;
|
||||
|
||||
public SaStorage storage;
|
||||
|
||||
public Box(SaRequest request, SaResponse response, SaStorage storage){
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
public SaRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public void setRequest(SaRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public SaResponse getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(SaResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public SaStorage getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public void setStorage(SaStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Box [request=" + request + ", response=" + response + ", storage=" + storage + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.dev33.satoken.context.model;
|
||||
|
||||
/**
|
||||
* Box 盒子类,用于存储 [ SaRequest、SaResponse、SaStorage ] 三个包装对象
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.16.0
|
||||
*/
|
||||
public class SaTokenContextModelBox {
|
||||
|
||||
public SaRequest request;
|
||||
|
||||
public SaResponse response;
|
||||
|
||||
public SaStorage storage;
|
||||
|
||||
public SaTokenContextModelBox(SaRequest request, SaResponse response, SaStorage storage) {
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
public SaRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public void setRequest(SaRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public SaResponse getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setResponse(SaResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public SaStorage getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public void setStorage(SaStorage storage) {
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Box [request=" + request + ", response=" + response + ", storage=" + storage + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +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.context.second;
|
||||
|
||||
/**
|
||||
* Sa-Token 二级Context - 创建器
|
||||
*
|
||||
* @author click33
|
||||
* @since 1.28.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SaTokenSecondContextCreator {
|
||||
|
||||
/**
|
||||
* 创建一个二级 Context 处理器
|
||||
* @return /
|
||||
*/
|
||||
SaTokenSecondContext create();
|
||||
|
||||
}
|
||||
@@ -206,6 +206,16 @@ public class SaTokenConsts {
|
||||
*/
|
||||
public static final int SA_TOKEN_CONTEXT_FILTER_ORDER = -104;
|
||||
|
||||
/**
|
||||
* RPC 框架权限过滤器的注册顺序
|
||||
*/
|
||||
public static final int RPC_PERMISSION_FILTER_ORDER = -30000;
|
||||
|
||||
/**
|
||||
* RPC 框架上下文过滤器的注册顺序
|
||||
*/
|
||||
public static final int RPC_CONTEXT_FILTER_ORDER = -30005;
|
||||
|
||||
/**
|
||||
* Content-Type key
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user