Spring缓存:如何在@Cacheable的unless中引用局部布尔变量?
解决@Cacheable中unless无法引用局部布尔变量的问题
你遇到的核心问题是:@Cacheable注解的SpEL表达式无法直接访问方法内部的局部变量,因为注解的SpEL解析时机在方法执行前后,局部变量仅在方法运行时存在,不在SpEL的可访问上下文里。下面给你两种可行的解决方案:
方案一:将判断标志存入返回对象
最直接的方式是给返回的Book类添加一个用于标记是否为部分数据的属性,然后在unless中通过返回值(#result)访问这个属性。
步骤1:修改Book类,添加标志属性
public class Book { private String title; // 原有其他属性... private boolean missingPages; // 新增标记属性 // 新增getter和setter public boolean isMissingPages() { return missingPages; } public void setMissingPages(boolean missingPages) { this.missingPages = missingPages; } // 原有getter/setter... }
步骤2:修改方法逻辑,设置标志并更新注解
@Cacheable(cacheNames="book", unless="#result.isMissingPages") public Book findBook(String name) { Book book = bookShelf.get(name); boolean isMissingPages = checkMissingPages(book); if (isMissingPages) { book.setTitle(book.getTitle() + " Missing Pages!"); book.setMissingPages(true); // 标记为部分数据 } else { book.setMissingPages(false); // 标记为完整数据(也可默认false,显式设置更清晰) } return book; }
方案二:使用包装类封装结果(不修改原有Book类)
如果不想改动Book类,可以创建一个包装类,同时保存Book对象和判断标志,然后在unless中判断包装类的标志:
步骤1:创建包装类
public class BookResult { private Book book; private boolean isPartialData; // 构造器、getter public BookResult(Book book, boolean isPartialData) { this.book = book; this.isPartialData = isPartialData; } public Book getBook() { return book; } public boolean isPartialData() { return isPartialData; } }
步骤2:修改方法返回类型和逻辑
@Cacheable(cacheNames="book", unless="#result.isPartialData") public BookResult findBook(String name) { Book book = bookShelf.get(name); boolean isMissingPages = checkMissingPages(book); if (isMissingPages) { book.setTitle(book.getTitle() + " Missing Pages!"); } return new BookResult(book, isMissingPages); }
补充说明:为什么原写法无效
你之前用的#root.target.isMissingPages是试图访问目标类的成员变量,但你代码里的isMissingPages是方法内部的局部变量,不属于类的成员,所以SpEL根本找不到这个变量,自然不会生效。
SpEL在@Cacheable注解中能访问的常用变量包括:
#result:方法的返回值#args:方法的参数数组#p0/#a0:方法的第一个参数(以此类推#p1/#a1对应第二个参数)#root.target:当前被调用的目标对象#root.method:当前被调用的方法
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

