Java Spring-Cache key配置注意事项介绍
程序员文章站
2024-04-01 21:49:04
为了提升项目的并发性能,考虑引入本地内存cache,对:外部数据源访问、restful api调用、可重用的复杂计算 等3种类型的函数处理结果进行缓存。目前采用的是spri...
为了提升项目的并发性能,考虑引入本地内存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实例代码解析等,如有不足之处,欢迎留言指出,小编会及时回复大家并修正,给广大编程爱好者提供更好的阅读体验,希望对大家有所帮助。在此也非常希望朋友们对本站多多支持!
上一篇: thinkPHP自动验证机制详解