Spring Caching配置缓存过期时间详解

 更新时间:2025年08月02日 09:20:55   作者:tag心动  
SpringCache基于AOP,通过注解实现缓存功能,抽象底层框架,默认使用Redis存储,支持多缓存配置,开启需添加注解,配置缓存项可指定过期时间

一、Spring Cache是什么?

它利用了AOP,实现了基于注解的缓存功能,并且进行了合理的抽象,业务代码不用关心底层是使用了什么缓存框架,只需要简单地加一个注解,就能实现缓存功能了。

而且Spring Cache也提供了很多默认的配置,用户可以3秒钟就使用上一个很不错的缓存功能。

工作流程:

  • 使用Spring Cache分为很简单的三步:添加依赖(springboot依赖包内置),开启缓存,加缓存注解。
  • 每次调用该方法时,都会检查缓存以查看调用是否已经运行并且不必重复。虽然在大多数情况下,只声明了一个缓存,但注释允许指定多个名称,以便使用多个缓存。在这种情况下,在调用该方法之前检查每个缓存 - 如果至少命中一个缓存,则返回关联的值。
  • 会触发一个后置处理,这会扫描每一个spring bean,查看是否已经存在缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。

特性:

  • 缓存数据是存在redis
  • 默认永不过期
  • key-value键、值队存储

二、使用步骤

开启基于注解的缓存

  • 在启动类添加以下注解
@EnableCaching

配置缓存

  • 在需要缓存数据的方法上面添加@Cacheable注解,即可缓存这个方法的返回值。
	@Cacheable(value = "DefaultKeyTest", keyGenerator = "simpleKeyGenerator", /*cacheNames = API_DETAIL_KEY_PREFIX, key = "target.redisApiDetailKeyPrefix + ':' + #appCode",*/ unless = "#result == null")
    public OpenApiDetailVo findByAppCode(String appCode) {
        return openApiAuthService.queryDetail(appCode);
    }

三、解决方案

方案一:通过编写config设置缓存相关项

  • 要指定 key 的过期时间,只需要getRedisCacheConfigurationMap方法中添加就可以。
@Configuration
public class RedisCacheConfig {

    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                stringBuilder.append(obj.toString());
            }
            stringBuilder.append("]");

            return stringBuilder.toString();
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl(600), // 默认策略,未配置的 key 会使用这个
                this.getRedisCacheConfigurationMap() // 指定 key 策略
        );
    }

    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
        redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(3000));
        redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));

        return redisCacheConfigurationMap;
    }

    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                RedisSerializationContext
                        .SerializationPair
                        .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofSeconds(seconds));

        return redisCacheConfiguration;
    }
}
  • 下面给出三种案例
	// 3000秒
    @Cacheable(value = "UserInfoList", keyGenerator = "simpleKeyGenerator")
    // 18000秒
    @Cacheable(value = "UserInfoListAnother", keyGenerator = "simpleKeyGenerator")
    // 600秒,未指定的key,使用默认策略
    @Cacheable(value = "DefaultKeyTest", keyGenerator = "simpleKeyGenerator")

方案二:通过配置文件

spring:
  # maximumSize:配置缓存的最大条数,当快要达到容量上限的时候,缓存管理器会根据一定的策略将部分缓存项移除。
  # expireAfterAccess:配置缓存项的过期机制,缓存项固定30秒将会过期,从而被移除。
  cache:
    caffeine:
      spec: maximumSize=500, expireAfterAccess=30s
    type: caffeine

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Mybatis下的SQL注入漏洞原理及防护方法解析

    Mybatis下的SQL注入漏洞原理及防护方法解析

    SQL 注入是发生在 Web 程序中数据库层的安全漏洞,是网站存在最多也是最简单的漏洞,在实际项目中,即使使用了 Mybatis 框架,但仍然有可能因为编码人员安全意识不足而导致 SQL 注入问题,这篇文章主要介绍了Mybatis下的SQL注入漏洞原理及防护方法 ,需要的朋友可以参考下
    2022-11-11
  • Java深入分析与解决Top-K问题

    Java深入分析与解决Top-K问题

    TopK问题即在N个数中找出最大的前K个,这篇文章将详细讲解三种方法解决TopK问题,文中代码具有一定参考价值,快跟随小编一起学习一下吧
    2022-04-04
  • Spring集成webSocket页面访问404问题的解决方法

    Spring集成webSocket页面访问404问题的解决方法

    这篇文章主要介绍了Spring集成webSocket页面访问404问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • 深入理解Hibernate中的flush机制

    深入理解Hibernate中的flush机制

    这篇文章主要介绍了深入理解Hibernate中的flush机制,本文是对flush机制深入研究得出的一些结论总结,需要的朋友可以参考下
    2015-01-01
  • Nginx+SpringCloud Gateway搭建项目访问环境

    Nginx+SpringCloud Gateway搭建项目访问环境

    本文主要介绍了Nginx+SpringCloud Gateway搭建项目访问环境,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Spring中ClassPathXmlApplicationContext类的使用详解

    Spring中ClassPathXmlApplicationContext类的使用详解

    这篇文章主要介绍了Spring中ClassPathXmlApplicationContext类的使用详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • JavaWeb开发实现备忘录

    JavaWeb开发实现备忘录

    这篇文章主要为大家详细介绍了JavaWeb开发实现备忘录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • MyBatis获取参数值的五种情况分析(推荐)

    MyBatis获取参数值的五种情况分析(推荐)

    本文通过实例代码给大家介绍MyBatis获取参数值的五种情况分析,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-11-11
  • Java中classpath讲解及使用方式

    Java中classpath讲解及使用方式

    本文详细讲解了Java中classpath讲解及使用方式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • java实现随机输出300题四则运算

    java实现随机输出300题四则运算

    本文主要介绍了java实现随机输出300题四则运算实例,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03

最新评论