不想每个查询条件service都带上租户ID作为jetcache的key,主要是已经通过sql拦截实现了多租户ID的注入,所以只能改造源码了
1.下载源码
2.找到CacheHandler.java中invokeWithCached、doUpdate、doInvalidate三个方法中修改key规则
原始代码如下
Object key = ExpressionUtil.evalKey(context, cic.getCachedAnnoConfig());
修改后代码如下
Object key = ExpressionUtil.evalKey(context, cic.getCachedAnnoConfig());
if(!ObjectUtils.isEmpty(UnifyAuthContextHolder.getUserInfo())){//判断租户是否为空,为空方法正常进行
UserInfo userInfo = UnifyAuthContextHolder.getUserInfo();
key = key+":"+userInfo.getTenantId();//添加租户ID
}
3.在refresh代码里把租户ID加入到上下文根拱service方法去刷新缓存,源码在RefreshCache中的内部类RefreshTask 修改在run方法上处理一下即可代码如下
public void run() {
try {
//处理多租户key放到登录用户中用于上下文根
if(key.toString().split(":").length>1){
AuthContext authContext = new AuthContext();
UserInfo userInfo = new UserInfo();
userInfo.setTenantId(key.toString().split(":")[key.toString().split(":").length-1]);
authContext.setUserInfo(userInfo);
Class clazz = UnifyThreadLocalSecurityContextHolderStrategy.class;
Field field = null;
try {
field = clazz.getDeclaredField("contextHolder");
field.setAccessible(true);
Constructor constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
ThreadLocal<AuthContext> value = (ThreadLocal<AuthContext>) field.get(constructor.newInstance());
value.set(authContext);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
if (config.getRefreshPolicy() == null || (loader == null && !hasLoader())) {
cancel();
return;
}
long now = System.currentTimeMillis();
long stopRefreshAfterLastAccessMillis = config.getRefreshPolicy().getStopRefreshAfterLastAccessMillis();
if (stopRefreshAfterLastAccessMillis > 0) {
if (lastAccessTime + stopRefreshAfterLastAccessMillis < now) {
logger.debug("cancel refresh: {}", key);
cancel();
return;
}
}
logger.debug("refresh key: {}", key);
Cache concreteCache = concreteCache();
if (concreteCache instanceof AbstractExternalCache) {
externalLoad(concreteCache, now);
} else {
load();
}
} catch (Throwable e) {
logger.error("refresh error: key=" + key, e);
}
}
这样就可以完成了jetcache基于多租户的缓存扩展了