SpringBoot整合Redis作为缓存(四)

Key生成策略

key.jpg

断点查看以上流程:

/org/springframework/cache/concurrent/ConcurrentMapCache.javalookup添加断点:

@Override
protected Object lookup(Object key) {
   return this.store.get(key);
}

执行debug在此断点前寻找:

findCachedItem:500, CacheAspectSupport

进入到类/org/springframework/cache/interceptor/CacheAspectSupport.java方法:

/**
 * Find a cached item only for {@link CacheableOperation} that passes the condition.
 * @param contexts the cacheable operations
 * @return a {@link Cache.ValueWrapper} holding the cached item,
 * or {@code null} if none is found
 */
private Cache.ValueWrapper findCachedItem(Collection<CacheOperationContext> contexts) {
   Object result = CacheOperationExpressionEvaluator.NO_RESULT;
   for (CacheOperationContext context : contexts) {
      if (isConditionPassing(context, result)) {
         Object key = generateKey(context, result);
         Cache.ValueWrapper cached = findInCaches(context, key);
         if (cached != null) {
            return cached;
         }
         else {
            if (logger.isTraceEnabled()) {
               logger.trace("No cache entry for key '" + key + "' in cache(s) " + context.getCacheNames());
            }
         }
      }
   }
   return null;
}

由此看出 key是由generateKey()生成

private Object generateKey(CacheOperationContext context, Object result) {
   Object key = context.generateKey(result);
   if (key == null) {
      throw new IllegalArgumentException("Null key returned for cache operation (maybe you are " +
            "using named params on classes without debug info?) " + context.metadata.operation);
   }
   if (logger.isTraceEnabled()) {
      logger.trace("Computed cache key '" + key + "' for operation " + context.metadata.operation);
   }
   return key;
}

继续往下:generateKey()

protected Object generateKey(Object result) {
   if (StringUtils.hasText(this.metadata.operation.getKey())) {
      EvaluationContext evaluationContext = createEvaluationContext(result);
      return evaluator.key(this.metadata.operation.getKey(), this.methodCacheKey, evaluationContext);
   }
   return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args);
}

看出key调用了keyGenerator.generate()

keyGenerator接口:

package org.springframework.cache.interceptor;

import java.lang.reflect.Method;

 
public interface KeyGenerator {
 
   Object generate(Object target, Method method, Object... params);

}

进入到 generate的 Simple实现类 SimpleKeyGenerator

package org.springframework.cache.interceptor;
import java.lang.reflect.Method;
public class SimpleKeyGenerator implements KeyGenerator {

   @Override
   public Object generate(Object target, Method method, Object... params) {
      return generateKey(params);
   }
 
   public static Object generateKey(Object... params) {
      if (params.length == 0) {
         return SimpleKey.EMPTY;
      }
      if (params.length == 1) {
         Object param = params[0];
         if (param != null && !param.getClass().isArray()) {
            return param;
         }
      }
      return new SimpleKey(params);
   }

}

SimpleKeyGenerator实现了KeyGenerator接口。

由此得出:

kay是使用KeyGenerator生成,spring-boot默认使用 SimpleKeyGenerator 。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容