Преглед на файлове

优化动态缓存注解,增加spel表达式指定参数作为缓存key

skyline преди 2 години
родител
ревизия
e6db38e579

+ 2 - 0
common/src/main/java/com/kym/common/annotation/DynamicCache.java

@@ -11,6 +11,8 @@ import java.lang.annotation.*;
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface DynamicCache {
+    String spel() default "";
+
     String value() default "";
 
     String key() default "";

+ 37 - 1
common/src/main/java/com/kym/common/aspect/DynamicCacheAspect.java

@@ -8,9 +8,15 @@ import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
 import org.springframework.stereotype.Component;
 
 import java.lang.reflect.Method;
+import java.util.Objects;
 
 /**
  * @author skyline
@@ -21,6 +27,8 @@ import java.lang.reflect.Method;
 @Aspect
 public class DynamicCacheAspect {
     private DynamicDataCache cache = DynamicDataCache.INSTANCE;
+    private SpelExpressionParser parserSpel = new SpelExpressionParser();
+    private DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
 
     @Pointcut("@annotation(com.kym.common.annotation.DynamicCache)")
     public void cachePointCut() {
@@ -31,12 +39,16 @@ public class DynamicCacheAspect {
         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
         Method method = signature.getMethod();
         DynamicCache dynamicCache = method.getAnnotation(DynamicCache.class);
+
+        //获取运行时参数的值
+        String spelParamValue = generateKeyBySpEL(dynamicCache.spel(), joinPoint);
+
         // 获取方法名
         var methodName = signature.getName();
         // 获取注解上的缓存时间
         var timeout = dynamicCache.timeout();
         // 获取注解上的缓存key
-        var key = dynamicCache.key();
+        var key = CommUtil.isEmptyOrNull(spelParamValue) ? methodName+":"+spelParamValue : dynamicCache.key();
         var data = cache.get(CommUtil.isEmptyOrNull(key) ? methodName : key);
         if (data != null) {
             return data;
@@ -47,4 +59,28 @@ public class DynamicCacheAspect {
         cache.put(CommUtil.isEmptyOrNull(key) ? methodName : key, result, timeout >= 0 ? timeout : 5 * 60 * 1000);
         return result;
     }
+
+    /**
+     * 生成缓存key
+     *
+     * @param key
+     * @param pjp
+     * @return
+     */
+    public String generateKeyBySpEL(String key, ProceedingJoinPoint pjp) {
+        if (CommUtil.isEmptyOrNull(key)) {
+            return null;
+        }
+        Expression expression = parserSpel.parseExpression(key);
+        EvaluationContext context = new StandardEvaluationContext();
+        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
+        Object[] args = pjp.getArgs();
+        String[] paramNames = parameterNameDiscoverer.getParameterNames(methodSignature.getMethod());
+        for (int i = 0; i < args.length; i++) {
+            assert paramNames != null;
+            context.setVariable(paramNames[i], args[i]);
+        }
+        return Objects.requireNonNull(expression.getValue(context)).toString();
+    }
+
 }

+ 2 - 0
service/src/main/java/com/kym/service/enplus/impl/EnPlusServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.crypto.digest.HMac;
 import cn.hutool.crypto.digest.HmacAlgorithm;
 import com.alibaba.fastjson2.JSONObject;
+import com.kym.common.annotation.DynamicCache;
 import com.kym.common.constant.ResponseEnum;
 import com.kym.common.enums.EnPlusApi;
 import com.kym.common.exception.BusinessException;
@@ -236,6 +237,7 @@ public class EnPlusServiceImpl implements EnPlusService {
      * @return
      */
     @Override
+    @DynamicCache(spel = "#connectorId")
     public JSONObject queryEquipBusinessPolicy(String equipBizSeq, String connectorId) {
         var param = """
                 {