基于jetcache扩展的多租户缓存

2022-08-16  本文已影响0人  负二贷

不想每个查询条件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基于多租户的缓存扩展了

上一篇 下一篇

猜你喜欢

热点阅读