Spring中如何基于Pageable参数生成缓存键?EL1008E报错解决
解决Spring @Cacheable中Pageable参数作为缓存键的异常问题
这个问题我之前也碰到过,核心原因是你直接访问了PageRequest的私有字段number,而SpEL在处理缓存键时只能识别公共属性或者对应的getter方法,PageRequest的number是私有变量,自然会抛出找不到属性的异常。下面给你几个可行的解决方案:
方案一:调用Pageable接口的公共getter方法生成键
org.springframework.data.domain.Pageable接口提供了一系列公共的getter方法,比如getPageNumber()、getPageSize()、getSort()等,SpEL可以直接调用这些方法(甚至可以简写为属性名的形式,比如pageNumber等价于getPageNumber())。
如果你只需要页码和每页大小作为缓存键,可以这样写:
@Cacheable(key = "#pageable.pageNumber + '_' + #pageable.pageSize") public Person getPersons(Pageable pageable) { // 你的业务逻辑 }
如果需要包含排序规则(避免相同页码但排序不同的结果被混存),可以加上排序参数:
@Cacheable(key = "#pageable.pageNumber + '_' + #pageable.pageSize + '_' + #pageable.sort") public Person getPersons(Pageable pageable) { // 你的业务逻辑 }
方案二:直接使用整个Pageable对象作为缓存键
Spring Data提供的PageRequest(以及其他Pageable实现类)已经正确实现了equals()和hashCode()方法,这意味着整个Pageable对象可以直接作为缓存键,自动包含所有分页相关参数(页码、每页大小、排序规则),写法更简洁:
@Cacheable(key = "#pageable") public Person getPersons(Pageable pageable) { // 你的业务逻辑 }
方案三:自定义缓存Key生成器(复杂场景适用)
如果你的缓存键需要更复杂的逻辑(比如结合其他参数、添加固定前缀等),可以自定义KeyGenerator:
首先实现KeyGenerator接口:
@Component("pageableKeyGenerator") public class PageableKeyGenerator implements KeyGenerator { @Override public Object generate(Object target, Method method, Object... params) { Pageable pageable = (Pageable) params[0]; // 自定义键的生成逻辑,比如添加方法名前缀 return method.getName() + "_" + pageable.getPageNumber() + "_" + pageable.getPageSize() + "_" + pageable.getSort(); } }
然后在@Cacheable注解中指定这个生成器:
@Cacheable(keyGenerator = "pageableKeyGenerator") public Person getPersons(Pageable pageable) { // 你的业务逻辑 }
内容的提问来源于stack exchange,提问作者Iti Gupta
相关产品推荐
相关产品推荐

