Spring Boot中JSR107缓存的Cache Key及重载方法失效问题
解决Spring Boot JSR107缓存的两个核心问题
针对你遇到的预填充缓存不生效、重载方法调用缓存方法失效的问题,咱们逐个拆解解决:
一、预填充缓存后仍触发API请求的原因与解决方案
你手动生成SimpleKey转字符串存入缓存的方式,和Spring处理@CacheResult时的键匹配逻辑不匹配。Spring在使用JSR107注解时,是直接用SimpleKey对象作为缓存键,而不是它的字符串表示。你存入的是字符串键,方法调用时用的是SimpleKey对象键,自然匹配不上,所以会触发API请求。
正确的预填充方式
直接使用SimpleKey对象作为键存入缓存,而不是转成字符串:
// 注入Spring的CacheManager @Autowired private CacheManager cacheManager; public void preFillCache(String bookId, BookCategory bookCategory, List<Book> deviceList) { // 生成和@CacheResult一致的SimpleKey对象 SimpleKey cacheKey = new SimpleKey(bookId, bookCategory); // 存入缓存 cacheManager.getCache("books.byidAndCat").put(cacheKey, deviceList); }
如果你的缓存实现是严格遵循JSR107规范的(比如Ehcache、Caffeine的JSR107适配),也可以直接用JSR107原生API操作:
@Autowired private javax.cache.CacheManager jCacheManager; public void preFillCache(String bookId, BookCategory bookCategory, List<Book> deviceList) { Cache<Object, List<Book>> cache = jCacheManager.getCache("books.byidAndCat", Object.class, List.class); SimpleKey key = new SimpleKey(bookId, bookCategory); cache.put(key, deviceList); }
二、重载方法调用缓存方法不生效的原因与解决方案
这是Spring缓存的经典代理陷阱:Spring缓存依赖动态代理实现拦截,同一个类内部的方法调用(包括重载方法调用目标缓存方法)不会经过代理对象,导致缓存拦截器无法生效。
解决方法
有两种常用方案可选:
- 拆分服务类:把标注
@CacheResult的getAllBooks方法抽到单独的Service类中,在重载方法所在类注入该Service,通过注入的实例调用缓存方法,强制走代理逻辑。 - 注入自身代理对象:在当前类中注入自己的Spring代理实例,用代理对象调用缓存方法:
@Service public class BookService { // 注入自身的代理对象 @Autowired private BookService selfProxy; // 重载方法 public List<Book> getAllBooks(String bookId) { // 用代理对象调用缓存方法 return selfProxy.getAllBooks(bookId, BookCategory.DEFAULT); } @CacheResult(cacheName = "books.byidAndCat") public List<Book> getAllBooks(@CacheKey final String bookId, @CacheKey final BookCategory bookCat) { return <<Make API calls and get actual books>>; } }
如果不想注入自身,也可以通过AopContext获取代理(需要在启动类添加@EnableAspectJAutoProxy(exposeProxy = true)):
public List<Book> getAllBooks(String bookId) { return ((BookService) AopContext.currentProxy()).getAllBooks(bookId, BookCategory.DEFAULT); }
内容的提问来源于stack exchange,提问作者Ruchira Kariyawasam
相关产品推荐
相关产品推荐

