微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpelEvaluationException:尝试调用空上下文对象上的方法

如何解决SpelEvaluationException:尝试调用空上下文对象上的方法

我正在尝试执行一个简单的缓存任务。我有一个 Holiday 对象,它有两个字段:referenceDateisHoliday。然后我有一个方法可以向休息 api 发出 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 不为空。也许在注释运行时它还没有被自动装配?这也是我第一次使用 SPEL,所以也许那里也有一些东西。如果实际上 cacheService 尚未自动装配,是否有解决方法

解决方法

因为您使用的是 @Cacheable(...) 注释,Spring 将使用上下文类 MethodBasedEvaluationContext 评估该 SpEL 表达式。这会将根对象设置为 CacheExpressionRootObject,并且将使用该根对象执行属性查找。

由于您尝试引用 bean 上的属性,因此最简单的解决方案是在 SpEL 表达式中直接引用该 bean。这是通过 @(例如 @myBeanName)完成的。然后,Spring 将在 ApplicationContext 中查找具有该名称的 bean。请记住,没有明确名称定义的 bean 将使用类名称的较低的驼峰命名。例如,名称为 MyBeanName 的类的 bean 名称为 myBeanName

尝试将您的 condition= 块更改为

@Cacheable(value = "holiday",key = "holidaycheck",condition = "@cacheService.isReferenceDateCached(#holidayDateToCheck)")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
    //some code to call a rest api
}
,

在SpEL的MethodBasedEvaluationContext中访问方法变量需要使用#,但是类变量不需要#。属性查找将自动查找没有 # 符号的属性的 getter。所以,你的 SpEL 应该是

cacheService.isReferenceDateCached(#holidayDateToCheck)

如果此 SpEL 不起作用,请尝试为 cacheService 创建 getter 方法。

,

试试

@Cacheable(value = "holiday",condition = "#{cacheService.isReferenceDateCached(#holidayDateToCheck)}")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
    //some code to call a rest api
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。