spring cache 本身不直接实现缓存自动淘汰与刷新,而是通过注解(如@cacheable、@cacheevict、@cacheput)声明缓存行为,并依赖底层缓存实现(如caffeine、redis、ehcache)及其配置策略(如expireafterwrite、ttl)来完成淘汰;自动刷新需借助refreshafterwrite、定时预热或自定义aop等机制实现,标准注解不支持后台异步刷新。

Java 中注解本身不直接实现缓存自动淘汰与刷新,它只是元数据标记;真正起作用的是配合注解的Spring Cache 抽象(如 @Cacheable、@CacheEvict、@CachePut)+ 具体缓存实现(如 Caffeine、Redis、Ehcache),再通过配置或扩展机制控制淘汰与刷新逻辑。
缓存自动淘汰:靠底层缓存提供者策略
注解不决定淘汰,而是由实际使用的缓存组件负责。例如:
-
Caffeine:支持基于大小(
maximumSize)、过期时间(expireAfterWrite/expireAfterAccess)、引用类型(weakKeys/softValues)等自动驱逐 -
Redis:通过设置 TTL(
EXPIRE)实现定时过期,由 Redis 自身清理 -
Ehcache:配置
timeToLiveSeconds、timeToIdleSeconds、maxEntriesLocalHeap等触发淘汰
Spring 的 @Cacheable 注解可通过 cacheManager 属性指定使用哪个缓存配置,间接启用对应淘汰策略。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
缓存自动刷新:需手动触发或结合定时/事件机制
标准 Spring Cache 不支持“后台自动刷新”(即缓存快过期时异步加载新值),但可通过以下方式模拟:
-
写操作联动刷新:用
@CachePut更新缓存(如修改用户后立即更新缓存中的用户信息) -
定时任务预热 + 过期短周期:设置较短 TTL(如 5 分钟),搭配
@Scheduled定时调用服务方法并写入缓存,确保热点数据常驻 -
Caffeine 的 refreshAfterWrite:在构建
Cache实例时启用该选项(注意:需配合CacheLoader),当访问过期条目时会异步刷新,旧值仍返回(适合容忍短暂陈旧数据的场景)
自定义注解增强刷新能力(进阶)
若需更灵活的刷新控制(如“访问前检查是否需刷新”),可自定义注解 + AOP:
- 定义如
@CacheableWithRefresh注解,携带refreshInterval参数 - 编写切面,在方法执行前检查缓存中数据是否超过刷新阈值;若满足,则异步调用原方法更新缓存(不影响当前响应)
- 注意线程安全和重复刷新问题,建议加分布式锁或本地锁控制并发刷新
关键提醒:避免常见误区
不要以为加了 @Cacheable 就自动“智能刷新”——它只做“有则取,无则查并存”,不感知业务语义。
- 缓存一致性必须由开发者保障:增删改操作要配对使用
@CacheEvict或@CachePut - 多实例部署时,本地缓存(如 Caffeine)无法共享,刷新/淘汰只在单机生效;跨节点需用 Redis 等集中式缓存
- 慎用
unless和condition,逻辑复杂易导致缓存未命中或误淘汰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










