当前位置: 移动技术网 > IT编程>开发语言>Java > Java Spring-Cache key配置注意事项介绍

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

为了提升项目的并发性能,考虑引入本地内存cache,对:外部数据源访问、restful api调用、可重用的复杂计算 等3种类型的函数处理结果进行缓存。目前采用的是spring cache的@cacheable注解方式,缓存具体实现选取的是guava cache。
具体缓存的配置此处不再介绍,重点对于key的配置进行说明:

1、基本形式

@cacheable(value="cachename", key"#id")  
public resultdto method(int id);  

2、组合形式

@cacheable(value="cachename", key"t(string).valueof(#name).concat('-').concat(#password))  
public resultdto method(int name, string password);  

3、对象形式

@cacheable(value="cachename", key"#user.id) 
public resultdto method(user user); 

4、自定义key生成器

@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(); 
  } 
} 

采用此方式后可以解决:多参数、原子类型数组、方法名识别 等问题

总结

以上就是本文关于java spring-cache key配置注意事项介绍的全部内容,感兴趣的朋友可以继续参阅:spark之standalone模式部署配置详解、、java之spring注解配置bean实例代码解析等,如有不足之处,欢迎留言指出,小编会及时回复大家并修正,给广大编程爱好者提供更好的阅读体验,希望对大家有所帮助。在此也非常希望朋友们对本站多多支持!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网