Spring Boot中如何为@Cacheable注解设置缓存过期TTL
Spring Boot @Cacheable 配置TTL过期时间方案
Spring 原生的@Cacheable注解没有内置TTL参数,过期时间需要结合你使用的具体缓存实现来配置,以下是两种主流场景的可用方案:
方案1:使用Caffeine(本地缓存场景)
- 第一步:引入依赖
<dependency> <groupId>com.github.benmanes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
- 第二步:配置缓存管理器,可统一或分别指定TTL
import com.github.benmanes.caffeine.cache.Caffeine; import org.springframework.cache.CacheManager; import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching public class CaffeineCacheConfig { // 统一所有缓存TTL @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager("userCache", "orderCache"); cacheManager.setCaffeine(Caffeine.newBuilder() // 设置写入后30分钟过期 .expireAfterWrite(30, TimeUnit.MINUTES) .maximumSize(1000)); return cacheManager; } // 不同缓存单独设置TTL可选方案 /* @Bean public CacheManager cacheManager() { Map<String, Caffeine<Object, Object>> cacheConfigs = new HashMap<>(); cacheConfigs.put("userCache", Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(500)); cacheConfigs.put("orderCache", Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).maximumSize(200)); CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeineSpecs(cacheConfigs); return cacheManager; } */ }
- 第三步:正常使用
@Cacheable注解即可,配置的TTL自动生效
@Cacheable(value = "userCache", key = "#userId") public User getUserById(Long userId) { // 业务查询逻辑 }
方案2:使用Redis(分布式缓存场景)
- 第一步:引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
- 第二步:配置Redis缓存管理器
import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import java.time.Duration; import java.util.HashMap; import java.util.Map; @Configuration @EnableCaching public class RedisCacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { // 全局默认TTL:2小时 RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofHours(2)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); // 单独为不同缓存设置不同TTL Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>(); cacheConfigs.put("userCache", defaultConfig.entryTtl(Duration.ofMinutes(15))); cacheConfigs.put("orderCache", defaultConfig.entryTtl(Duration.ofMinutes(30))); return RedisCacheManager.builder(connectionFactory) .cacheDefaults(defaultConfig) .withInitialCacheConfigurations(cacheConfigs) .build(); } }
- 第三步:直接使用
@Cacheable注解即可
无需自定义序列化规则时,可直接在配置文件中设置全局TTL,无需写配置类:
spring: cache: type: redis redis: time-to-live: 3600000 # 单位毫秒,此处为1小时
常见不生效问题排查
- 检查启动类或配置类是否加了
@EnableCaching注解开启缓存功能 - 确认项目只引入了一种缓存实现依赖,多缓存实现共存会导致优先级冲突
- 普通场景下按缓存名称配置TTL即可覆盖绝大多数需求,如需在
@Cacheable注解层面动态指定TTL,可自定义缓存注解扩展后通过SpEL表达式解析处理
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

