源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Java Spring-Cache key配置注意事项介绍

  • 时间:2020-03-10 13:08 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Java Spring-Cache key配置注意事项介绍
为了提升项目的并发性能,考虑引入本地内存Cache,对:外部数据源访问、Restful API调用、可重用的复杂计算 等3种类型的函数处理结果进行缓存。目前采用的是spring Cache的@Cacheable注解方式,缓存具体实现选取的是Guava Cache。 具体缓存的配置此处不再介绍,重点对于key的配置进行说明: [b]1、基本形式[/b]
@Cacheable(value="cacheName", key"#id")  
public ResultDTO method(int id);  
[b]2、组合形式[/b]
@Cacheable(value="cacheName", key"T(String).valueOf(#name).concat('-').concat(#password))  
public ResultDTO method(int name, String password);  
[b]3、对象形式[/b]
@Cacheable(value="cacheName", key"#user.id) 
public ResultDTO method(User user); 
[b]4、自定义key生成器[/b]
@Cacheable(value="gomeo2oCache", keyGenerator = "keyGenerator") 
public ResultDTO method(User user); 
注意:Spring默认的SimpleKeyGenerator是不会将函数名组合进key中的 如下:
@Component 
public class CacheTestImpl implements CacheTest { 
  @Cacheable("databaseCache") 
  public Long test1() 
  { return 1L; } 
  @Cacheable("databaseCache") 
  public Long test2() 
  { return 2L; } 
  @Cacheable("databaseCache") 
  public Long test3() 
  { return 3L; } 
  @Cacheable("databaseCache") 
  public String test4() 
  { return "4"; } 
} 
我们期望输出:
1 
2 
3 
4
实际却输出:
1 
1 
1 
ClassCastException: java.lang.Long cannot be cast to java.lang.String 
此外,原子类型的数组,直接作为key使用也是不会生效的 为了解决上述2个问题,自定义了一个KeyGenerator如下:
class CacheKeyGenerator implements KeyGenerator { 
  // custom cache key 
  public static final int NO_PARAM_KEY = 0; 
  public static final int NULL_PARAM_KEY = 53; 
  @Override 
  public Object generate(Object target, Method method, Object... params) { 
    StringBuilder key = new StringBuilder(); 
    key.append(target.getClass().getSimpleName()).append(".").append(method.getName()).append(":"); 
    if (params.length == 0) { 
      return key.append(NO_PARAM_KEY).toString(); 
    } 
    for (Object param : params) { 
      if (param == null) { 
        log.warn("input null param for Spring cache, use default key={}", NULL_PARAM_KEY); 
        key.append(NULL_PARAM_KEY); 
      } else if (ClassUtils.isPrimitiveArray(param.getClass())) { 
        int length = Array.getLength(param); 
        for (int i = 0; i < length; i++) { 
          key.append(Array.get(param, i)); 
          key.append(','); 
        } 
      } else if (ClassUtils.isPrimitiveOrWrapper(param.getClass()) || param instanceof String) { 
        key.append(param); 
      } else { 
        log.warn("Using an object as a cache key may lead to unexpected results. " + 
            "Either use @Cacheable(key=..) or implement CacheKey. Method is " + target.getClass() + "#" + method.getName()); 
        key.append(param.hashCode()); 
      } 
      key.append('-'); 
    } 
    String finalKey = key.toString(); 
    long cacheKeyHash = Hashing.murmur3_128().hashString(finalKey, Charset.defaultCharset()).asLong(); 
    log.debug("using cache key={} hashCode={}", finalKey, cacheKeyHash); 
    return key.toString(); 
  } 
} 
采用此方式后可以解决:多参数、原子类型数组、方法名识别 等问题 [b]总结[/b] 以上就是本文关于Java Spring-Cache key配置注意事项介绍的全部内容,感兴趣的朋友可以继续参阅:[url=http://www.1sucai.cn/article/125784.htm]spark之Standalone模式部署配置详解[/url]、[url=http://www.1sucai.cn/article/124399.htm]struts2开发流程及详细配置[/url]、[url=http://www.1sucai.cn/article/124326.htm]Java之Spring注解配置bean实例代码解析[/url]等,如有不足之处,欢迎留言指出,小编会及时回复大家并修正,给广大编程爱好者提供更好的阅读体验,希望对大家有所帮助。在此也非常希望朋友们对本站多多支持!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部