我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring @Cacheable指定失效时间方法是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring @Cacheable指定失效时间方法是什么

这篇文章主要介绍“Spring @Cacheable指定失效时间方法是什么”,在日常操作中,相信很多人在Spring @Cacheable指定失效时间方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring @Cacheable指定失效时间方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Spring @Cacheable指定失效时间

新版本配置

@Configuration@EnableCachingpublic class RedisCacheConfig {    @Bean    public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {        return (builder) -> {            for (Map.Entry<String, Duration> entry : RedisCacheName.getCacheMap().entrySet()) {                builder.withCacheConfiguration(entry.getKey(),                        RedisCacheConfiguration.defaultCacheConfig().entryTtl(entry.getValue()));            }        };    }     public static class RedisCacheName {         public static final String CACHE_10MIN = "CACHE_10MIN";         @Getter        private static final Map<String, Duration> cacheMap;         static {            cacheMap = ImmutableMap.<String, Duration>builder().put(CACHE_10MIN, Duration.ofSeconds(10L)).build();        }     }  }

老版本配置

interface CacheNames{    String CACHE_15MINS = "sssss:cache:15m";            String CACHE_30MINS = "sssss:cache:30m";            String CACHE_60MINS = "sssss:cache:60m";            String CACHE_180MINS = "sssss:cache:180m";} @Component public class RedisCacheCustomizer            implements CacheManagerCustomizer<RedisCacheManager> {                @Override        public void customize(RedisCacheManager cacheManager) {            // 自定义缓存名对应的过期时间            Map<String, Long> expires = ImmutableMap.<String, Long>builder()                    .put(CacheNames.CACHE_15MINS, TimeUnit.MINUTES.toSeconds(15))                    .put(CacheNames.CACHE_30MINS, TimeUnit.MINUTES.toSeconds(30))                    .put(CacheNames.CACHE_60MINS, TimeUnit.MINUTES.toSeconds(60))                    .put(CacheNames.CACHE_180MINS, TimeUnit.MINUTES.toSeconds(180)).build();            // spring cache是根据cache name查找缓存过期时长的,如果找不到,则使用默认值            cacheManager.setDefaultExpiration(TimeUnit.MINUTES.toSeconds(30));            cacheManager.setExpires(expires);        }    }    @Cacheable(key = "key", cacheNames = CacheNames.CACHE_15MINS)    public String demo2(String key) {        return "abc" + key;  }

@Cacheable缓存失效时间策略默认实现及扩展

之前对Spring缓存的理解是每次设置缓存之后,重复请求会刷新缓存时间,但是问题排查阅读源码发现,跟自己的理解大相径庭。所有的你以为都仅仅是你以为!!!!

背景

目前项目使用的spring缓存,主要是CacheManager、Cache以及@Cacheable注解,Spring现有的缓存注解无法单独设置每一个注解的失效时间,Spring官方给的解释:Spring Cache是一个抽象而不是一个缓存实现方案。

因此对于缓存失效时间(TTL)的策略依赖于底层缓存中间件,官方给举例:ConcurrentMap是不支持失效时间的,而Redis是支持失效时间的。

Spring @Cacheable指定失效时间方法是什么

Spring Cache Redis实现

Spring缓存注解@Cacheable底层的CacheManager与Cache如果使用Redis方案的话,首次设置缓存数据之后,每次重复请求相同方法读取缓存并不会刷新失效时间,这是Spring的默认行为(受一些缓存影响,一直以为每次读缓存也会刷新缓存失效时间)。

可以参见源码:

org.springframework.cache.interceptor.CacheAspectSupport#execute(org.springframework.cache.interceptor.CacheOperationInvoker, java.lang.reflect.Method, org.springframework.cache.interceptor.CacheAspectSupport.CacheOperationContexts)

private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {// Special handling of synchronized invocationif (contexts.isSynchronized()) {CacheOperationContext context = contexts.get(CacheableOperation.class).iterator().next();if (isConditionPassing(context, CacheOperationExpressionEvaluator.NO_RESULT)) {Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);Cache cache = context.getCaches().iterator().next();try {return wrapCacheValue(method, cache.get(key, () -> unwrapReturnValue(invokeOperation(invoker))));}catch (Cache.ValueRetrievalException ex) {// The invoker wraps any Throwable in a ThrowableWrapper instance so we// can just make sure that one bubbles up the stack.throw (CacheOperationInvoker.ThrowableWrapper) ex.getCause();}}else {// No caching required, only call the underlying methodreturn invokeOperation(invoker);}}  // Process any early evictionsprocessCacheEvicts(contexts.get(CacheEvictOperation.class), true,CacheOperationExpressionEvaluator.NO_RESULT); // Check if we have a cached item matching the conditionsCache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class)); // Collect puts from any @Cacheable miss, if no cached item is foundList<CachePutRequest> cachePutRequests = new LinkedList<>();if (cacheHit == null) {collectPutRequests(contexts.get(CacheableOperation.class),CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);} Object cacheValue;Object returnValue; if (cacheHit != null && !hasCachePut(contexts)) {// If there are no put requests, just use the cache hitcacheValue = cacheHit.get();returnValue = wrapCacheValue(method, cacheValue);}else {// Invoke the method if we don't have a cache hitreturnValue = invokeOperation(invoker);cacheValue = unwrapReturnValue(returnValue);} // Collect any explicit @CachePutscollectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests); // Process any collected put requests, either from @CachePut or a @Cacheable missfor (CachePutRequest cachePutRequest : cachePutRequests) {cachePutRequest.apply(cacheValue);} // Process any late evictionsprocessCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue); return returnValue;}

因此如果我们需要自行控制缓存失效策略,就可能需要一些开发工作,具体如下。

Spring Cache 失效时间自行刷新

基于Spring的Cache组件进行定制,对get方法进行重写,刷新过期时间。相对简单,不难;此处不贴代码了。

可以使用后台线程进行定时的缓存刷新,以达到刷新时间的作用。

使用spring data redis模块,该模块提供对了TTL更新策略的,可以参见:org.springframework.data.redis.core.PartialUpdate

注意:

Spring对于@Cacheable注解是由spring-context提供的,spring-context提供的缓存的抽象,是一套标准而不是实现。

而PartialUpdate是由于spring-data-redis提供的,spring-data-redis是一套spring关于redis的实现方案。

到此,关于“Spring @Cacheable指定失效时间方法是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring @Cacheable指定失效时间方法是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring @Cacheable指定失效时间方法是什么

这篇文章主要介绍“Spring @Cacheable指定失效时间方法是什么”,在日常操作中,相信很多人在Spring @Cacheable指定失效时间方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”S
2023-06-22

session php默认失效时间是什么

本文小编为大家详细介绍“session php默认失效时间是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“session php默认失效时间是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。session
2023-07-04

redis@Cacheable注解以及过期时间设置方式是什么

redis@Cacheable注解以及过期时间设置方式是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。原理解释 友情链接 手写redis @ Cacheable注解参
2023-06-22

spring动态设置定时任务的方法是什么

在Spring中,可以使用`TaskScheduler`接口和`@Scheduled`注解来动态设置定时任务。1. 使用`TaskScheduler`接口:```java@Autowiredprivate TaskScheduler tas
2023-08-25

Spring中为bean指定InitMethod和DestroyMethod的执行方法是什么

Spring中为bean指定InitMethod和DestroyMethod的执行方法是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.创建一个类/** * @aut
2023-06-21

mongodb时间戳转时间的方法是什么

在MongoDB中要将时间戳转换为时间,可以使用new Date(timestamp)方法。其中timestamp为时间戳的值,单位为毫秒。以下是一个示例:var timestamp = 1612981838830; // 一个时间戳的示
mongodb时间戳转时间的方法是什么
2024-04-09

vue3自定义指令方法是什么

这篇文章主要讲解了“vue3自定义指令方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue3自定义指令方法是什么”吧!一、注册自定义指令以下实例都是实现一个输入框自动获取焦点的自定
2023-06-21

java空间换时间的方法是什么

Java空间换时间的方法是使用缓存。在程序运行过程中,将一些计算结果或者数据保存在缓存中,当需要使用的时候直接从缓存中取出,避免了重复计算或者重复查询数据库等操作,从而提高了程序的执行效率。缓存可以使用Java集合类或者第三方缓存库实现,如
2023-05-31

java random指定范围的方法是什么

在Java中,可以使用 Random 类的 nextInt 方法来生成指定范围的随机数。该方法有两个重载的版本:1. `nextInt(int n)`:生成一个在 0(包括)和 n(不包括)之间的随机数。2. `nextInt(int mi
2023-08-31

spring-session自定义序列化方法是什么

本篇内容介绍了“spring-session自定义序列化方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!spring-session
2023-06-22

vue3自定义指令的方法是什么

这篇文章主要介绍“vue3自定义指令的方法是什么”,在日常操作中,相信很多人在vue3自定义指令的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”vue3自定义指令的方法是什么”的疑惑有所帮助!接下来
2023-07-04

tomcat启动指定jdk的方法是什么

要在Tomcat中指定使用特定的JDK,请按照以下步骤操作:1. 确保已经安装了所需版本的JDK,并且已经配置好了环境变量。2. 打开Tomcat的启动脚本文件,该文件通常位于Tomcat的bin目录下。在Windows上,脚本文件名为`c
2023-10-10

mysql导出指定表的方法是什么

使用MySQL命令行工具进行导出指定表的方法如下:打开命令行工具,输入以下命令连接到MySQL数据库:mysql -u username -p database_name其中,username是数据库用户名,database_name是数据
mysql导出指定表的方法是什么
2024-04-09

gridview编辑指定列的方法是什么

GridView编辑指定列的方法有多种,可以通过以下几种方式实现:1. 使用TemplateField模板列:在GridView中添加TemplateField列,然后在ItemTemplate中添加编辑控件,例如TextBox、DropD
2023-09-11

linux kill指定进程的方法是什么

在Linux中,可以使用kill命令来终止指定的进程。kill命令的使用格式为:kill [options] 其中,[options]是可选的参数,可以用于指定终止进程的方式,是要终止的进程号。以下是一些常用的kill命令选项:-9或--s
2023-09-22

plsql定时备份的方法是什么

在PL/SQL中实现定时备份的方法有很多种,其中一种常用的方法是使用DBMS_SCHEDULER包来创建和管理定时任务。下面是一个示例代码来创建一个定时备份的任务:-- 创建定时任务BEGINDBMS_SCHEDULER.create_
plsql定时备份的方法是什么
2024-04-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录