我正在尝试做一个简单的缓存任务。我有一个Holiday对象,它有两个字段:referenceDate和isHoliday。然后,我有一个方法,它将向rest发出HTTP请求,以检查某个日期是否是假日。我想实现的是:如果当前缓存的Holiday对象与作为参数传递的对象具有相同的referenceDate,则返回缓存的值。我有一个特定的类来执行那个检查。以下是代码:
假日
@AllArgsConstructor
@Getter
public class Holiday {
public LocalDate referenceDate;
public boolean isHoliday;
}CacheService类
@DomainService
public class CacheService {
@Autowired
private CacheManager cacheManager;
public boolean isReferenceDateCached(final LocalDate referenceDate){
final Holiday holiday = (Holiday) cacheManager.getCache("holiday").get("holidaycheck");
return(holiday.getReferenceDate().equals(referenceDate));
}
}HolidatInfraService类
@AllArgsConstructor
@Service
@Slf4j
public class HolidayInfraService {
@Autowired
private final CacheService cacheService;
@Cacheable(value = "holiday", key = "holidaycheck", condition = "#cacheService.isReferenceDateCached(#holidayDateToCheck)")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
//some code to call a rest api
}
}这就是我尝试holidayInfraService.isHoliday(someDate)时从单元测试中得到的错误
org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method isReferenceDateCached(java.time.LocalDate) on null context object从这个异常消息看来,cacheService是空的,这是非常明显的。但是,当我删除代码并进入isHoliday时,cacheService不是空的。也许在注释运行的时候,它还没有自动完成呢?这也是我第一次和斯皮尔一起工作,所以也许也有一些事情要做。如果实际上cacheService还不是自动设置的,那么有解决办法吗?
发布于 2021-06-18 14:55:19
因为您使用的是@Cacheable(...)注释,所以Spring将使用上下文类MethodBasedEvaluationContext计算该SpEL表达式。这将将根对象设置为CacheExpressionRootObject,并将使用该根对象执行属性查找。
由于您试图引用bean上的属性,最简单的解决方案是在SpEL表达式中直接引用该bean。这是用@ (例如@myBeanName)完成的。然后Spring将在ApplicationContext中查找具有该名称的bean。请记住,没有显式名称的bean将使用类名的下camel命名。例如,名为MyBeanName的类将有一个名为myBeanName的bean名称。
尝试将condition=块更改为
@Cacheable(value = "holiday", key = "holidaycheck", condition = "@cacheService.isReferenceDateCached(#holidayDateToCheck)")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
//some code to call a rest api
}发布于 2021-06-18 14:46:00
在SpEL的MethodBasedEvaluationContext to access方法变量中,您需要使用#,但类变量不需要#。属性查找将自动查找没有#符号的属性的getter。所以,你的SpEL应该是
cacheService.isReferenceDateCached(#holidayDateToCheck)如果这个SpEL不能工作,请尝试为cacheService创建getter方法。
发布于 2021-06-18 16:03:28
试一试
@Cacheable(value = "holiday", key = "holidaycheck", condition = "#{cacheService.isReferenceDateCached(#holidayDateToCheck)}")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
//some code to call a rest api
}https://stackoverflow.com/questions/68036916
复制相似问题