美文网首页
SpringBoot整合Redis作为缓存(四)

SpringBoot整合Redis作为缓存(四)

作者: Invi | 来源:发表于2019-05-05 17:31 被阅读0次

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 。

相关文章

网友评论

      本文标题:SpringBoot整合Redis作为缓存(四)

      本文链接:https://www.haomeiwen.com/subject/skihoqtx.html