Spring-Cache key设置注意事项

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

为了提升项目的并发性能,考虑引入本地内存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();
    }
}

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



Spring Cache使用Redis自定义缓存key 本篇博客,简单的介绍了sprig cachespring cache如何使用redis作为缓存,已经自定义缓存key策略,以及通过配置缓存过期时间 阅读详情

相关推荐

【看源码】@Cacheable和@CacheEvict的原理, 批量key过期失效的原因分析

最近发现自己搭的一个项目返回的数据不太准确, 第一时间想到了是缓存的问题, 缓存代码如下}有个困扰我很久的问题就是allroom的evict是否生效.类似上面这个场景, 我们经常有list()方法没指定key缓存了全部数据, 以及指定了key是id缓存了单个数据, 最后我们在方法想evict过期上面两种缓存众所周知 @Cacheable 和 @CacheEvict 的使用要求其中之一就是value和key一样, 以及方法参数要一样. 因此单个的evict肯定没问题, 问题是所有的如何过期呢。

zzzgd_666的博客 2772

Spring Cache 自定义缓存 key

以参数id作为key会出现逻辑错误,当调用第一次getUserByid2方法时,存入key为id,值为dong,当调用第二次getUserByid2方法时,因为已经存入缓存id,所以不会进入第二次getUserByid2方法,所以lisi不能进入缓存

泠青沼 1973

Spring-CacheKey 设置注意事项

在现代企业级开发中,缓存是优化系统性能、提升响应速度的关键技术之一。Spring 框架通过提供了简单而强大的缓存支持,开发者可以轻松实现方法级缓存、减少数据库或外部服务的调用。然而,缓存的命中率是评估缓存系统效率的重要指标,而Cache Key的设计直接决定了缓存的命中率。在上期中,我们讨论了 Spring Cache 的核心原理与基本使用,包括注解方式的缓存设置、缓存的存储位置以及生命周期管理等内容。本期将深入解析Spring Cache Key设置注意事项

喵手的博客 961

Spring-Cache的基本使用和缺点

Spring官方支持了一些配置,帮助我们操作缓存。(官方学习文档)可以帮我们简化很多操作,只需要使用几个注解,就可以帮助我们对更改的操作写入到缓存中。本文推荐使用失效模式

m0_56466015的博客 7832

memcached安装使用

http://www.cnblogs.com/whoknows/articles/memcache_php5-3-10_win32.html  introduce http://blog.couchbase.com/memcached-144-windows-32-bit-binary-now-available  down http://www.cnblogs.com

paolei的笔记 2884

Spring之—— Spring-Cache key设置注意事项

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

冰河的专栏 1万+

Spring-Cache key设置注意事项,及自定义keyGenerator

为了提升项目的并发性能,考虑引入本地内存Cache,对:外部数据源访问、Restful API调用、可重用的复杂计算 等3种类型的函数处理结果进行缓存。目前采用的是Spring Cache的@Cacheable注解方式,缓存具体实现选取的是Guava Cache。 具体缓存的配置此处不再介绍,重点对于key的配置进行说明: 1、基本形式 @Cacheable(value="cacheName"......

tongshuixu8025的博客 1万+

spring Cache和redis整合注意事项

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33725126的博客 137

Spring Cache的详细使用

Spring CacheSpring 框架提供的缓存抽象层,它通过注解的方式简化缓存的使用,允许开发者在不修改业务逻辑的情况下,轻松地为方法添加缓存功能。它支持多种缓存实现(如 Redis、Ehcache、Caffeine 等),并提供统一的 API 进行管理。

weixin_52580607的博客 1284

spring cache

1.想用redistemplate作为缓存,被领导制止了,指定用spring cache 2.自我理解:spring cache也是一个缓存,方便存储对象,但是缓存底层可以选择redis 3.spring cache+redis的好处 解决缓存不同步的情况 解决springcache占用内存的情况 集群环境下,每台服务器的spring cache是不同步的,这样会出问题的, spring cache只适合单机环境 redis是设置单独的缓存服务器,所有集群服务器统一访问redis,不会出现...

qq_35653822的博客 1104

【详解】Spring-Cachekey设置注意事项

正确设置缓存键是确保Spring Cache功能有效性的关键。通过合理使用默认缓存键生成器、自定义缓存键以及注意一些常见的陷阱,可以显著提升系统的性能和稳定性。希望本文对大家在实际开发中使用Spring Cache有所帮助。这篇文章详细介绍了Spring Cache中缓存键的设置方法和注意事项,希望能够帮助开发者更好地理解和使用Spring Cache功能。在使用Spring Cache时,正确配置缓存键(Cache Key)是非常重要的,它直接影响到缓存的命中率和数据的一致性。

牛肉胡辣汤 1860

Spring Cache简介和使用

Spring Cache缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存。本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 cache 配置方法,展现了 spring cache 的强大之处,然后介绍了其基本的原理,扩展点和使用场景的限制。通过阅读本文,你应该可以短时间内掌握 spring 带来的强大缓存技术,在很少的配置下即可给

Alvin的专栏 2989

5、spring-boot-starter-cache 介绍和在 Spring Boot 中集成使用

Spring Boot Cache Starter 详解 spring-boot-starter-cacheSpring Boot 提供的缓存抽象模块,它通过注解方式简化缓存集成,支持多种缓存实现(Redis、Caffeine等)。核心功能包括: 声明式缓存:通过@Cacheable、@CacheEvict等注解实现自动缓存管理 缓存抽象:业务代码不依赖具体缓存技术 自动配置:根据依赖自动配置CacheManager 多级缓存:支持本地+分布式缓存组合 使用步骤: 添加spring-boot-star

python15397的博客 1481

spring cache(四)cache key集中管理和cache version管理

上述代码不支持批量删除缓存,再比如根据key模糊删除等也是不支持的,这种情况需要自定义删除方法。2.1、自定义RedisCache,重写evict方法2.2、自定义RedisCacheManager,使用自定义的RedisCache2.3、在RedisConfig中使用自定义的RedisCacheManager。

w_t_y_y的博客 616

Spring Cache

缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存。 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 cache 配置方法,展现了 spring cache 的强大之处,然后介绍了其基本的原理,扩展点和使用场景的限制。通过阅读本文,你应该可以短时间内掌握 spring 带来的强大缓存技术,在很少的配置下即可给既有...

窦再兴的博客 265

Spring Cache(学习笔记)

Spring Cache快速使用

2301_82119611的博客 596

注释驱动的 Spring cache 缓存介绍

概述 Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。 Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Exp...

weixin_30616969的博客 122

基于Anocation的Spring Cache

概述 Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。 Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring

end's coding life 1171

data spring 指定时区_今天的工作内容:Spring Boot 2.X整合Spring-cache

计算机领域有人说过一句名言:“计算机科学领域的任何问题都可以通过增加一个中间层来解决”,今天我们就用Spring-cache给网站添加一层缓存,让你的网站速度飞起来。本文目录一、Spring Cache介绍二、缓存注解介绍三、Spring Boot+Cache实战1、pom.xml引入jar包2、启动类添加@EnableCaching注解3、配置数据库和redis连接4、配置CacheManage...

weixin_35701203的博客 93
上一篇: 使用 Maven Profile 和 Filtering 打各种环境的包
下一篇: Python中文处理:str与unicode
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值