cacheable注解原理_Spring Cacheable(Redis)扩展实现注解式TTL

本文介绍了如何在Spring中扩展@Cacheable注解,以实现基于Redis的注解式TTL。通过创建自定义的@CacheableTtl注解、TtlRedisCacheManager和TtlCacheResolver,实现了动态设置缓存过期时间的功能。详细过程包括分析Spring Cache的源码,寻找扩展点,并给出完整的解决方案。
摘要由CSDN通过智能技术生成

1、背景

咱们在项目当中常常要使用redis做为缓存,可选择的方式有:1)编程方式 2)注解方式java

1. 编程方式

jedis

redisTempate

redisson

2. 注解方式

spring cache系列注解

经过切面自定义注解实现

因为spring @Cacheable提供了多种缓存实现,有的缓存是不支持ttl的,所以@Cacheable注解当中是没有设置ttl参数的,Redis实现的Cache,配置ttl必须单独集中配置,以下:

RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory)

.cacheDefaults(defaultConfig);

Map cacheConfigurations = new HashMap<>();

// 自定义每一个cacheName的配置

RedisCacheConfiguration config = cacheDefault(resourceLoader);

config = config.entryTtl(Duration.ofMinutes(30));

cacheConfigurations.put("store", config);

cacheConfigurations.put("store-nearby", defaultConfig);

return builder.withInitialCacheConfigurations(cacheConfigurations).build();

这样作有spring的道理,可是确实感受不是很灵活,团队以前也基于切面实现了一套支持ttl的注解。最近项目架构升级到spring-boot,能不能基于spring-boot-data-redis扩展实现注解方式的ttl?git

2、思路

1. 增长切面

好比,咱们自定义一个@Ttl注解,若是一个方法上面同时有@Cacheable @Ttl注解,咱们解析对应Redis Key, 方法执行结束后,给对应的key设置过时时间web

2. 找SpringCache扩展点

Debug代码,寻找扩展点进行扩展。redis

通过比较,我发现spring生成key的策略是比较复杂的,RedisCacheConfiguration能够配置前缀,KeyGenerator又能够自定义配置key的生成策略。实现代码解析key难度较大,而且容易出现bug,直接放弃这种方式。由于咱们要经过反射拿到方法上的ttl时间,咱们这个扩展点首先要能获取当前执行的Method,奔着目标,debug代码,我把目标放在了RedisCache、CacheAspectSupport、CacheResolver、RedisCacheManager这几个类上。spring

RedisCache

@Override

public void put(Object key, @Nullable Object value) {

Object cacheValue = preProcessCacheValue(value);

if (!isAllowNullValues() && cacheValue == null) {

throw new IllegalArgumentException(String.format(

"Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisCacheConfiguration.",

name));

}

cacheWriter.put(name, createAndConvertCacheKey(key), serializeCacheValue(cacheValue), cacheConfig.getTtl());

}

重点代码编程

cacheWriter.put(name, createAndConvertCacheKey(key), serializeCacheValue(cacheValue), cacheConfig.getTtl());

这一行代码,我能够看出来,ttl是从全局变量cacheConfig的getTtl()获取的,下一步我要找到RedisCache的实例是何时生成并注入cacheConfig的。缓存

CacheAspectS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值