SpelEvaluationException:尝试调用 null 上下文对象上的方法
SpelEvaluationException: Attempted to call method on null context object
我正在尝试执行一个简单的缓存任务。我有一个 Holiday
对象,它有两个字段:referenceDate
和 isHoliday
。然后我有一个方法可以向 rest api 发出 HTTP 请求,以检查日期是否为假期。我想要实现的是:如果当前缓存的 Holiday
对象与作为参数传递的对象具有相同的 referenceDate,return 缓存的值。我有一个特定的 class 来执行该检查。这是代码:
假期class
@AllArgsConstructor
@Getter
public class Holiday {
public LocalDate referenceDate;
public boolean isHoliday;
}
缓存服务class
@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 class
@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
还没有自动装配,是否有解决方法?
在SpEL的MethodBasedEvaluationContext
中访问方法变量,需要使用#
,但class变量不需要#
。 属性 查找将自动为没有 #
符号的 属性 找到 getter。所以,你的 SpEL 应该是
cacheService.isReferenceDateCached(#holidayDateToCheck)
如果此 SpEL 不起作用,请尝试为 cacheService
创建 getter 方法。
因为您正在使用 @Cacheable(...)
注释,Spring 将使用上下文 class MethodBasedEvaluationContext
评估该 SpEL 表达式。这会将根对象设置为 CacheExpressionRootObject
,并且将使用该根对象执行 属性 查找。
由于您试图在 bean 上引用 属性,最简单的解决方案是在 SpEL 表达式中直接引用该 bean。这是通过 @
(例如 @myBeanName
)完成的。 Spring 然后将在 ApplicationContext
中查找具有该名称的 bean。请记住,没有显式名称定义的 bean 将使用 class 名称的小驼峰命名。例如,名称为 MyBeanName
的 class 的 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
}
尝试
@Cacheable(value = "holiday", key = "holidaycheck", condition = "#{cacheService.isReferenceDateCached(#holidayDateToCheck)}")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
//some code to call a rest api
}
我正在尝试执行一个简单的缓存任务。我有一个 Holiday
对象,它有两个字段:referenceDate
和 isHoliday
。然后我有一个方法可以向 rest api 发出 HTTP 请求,以检查日期是否为假期。我想要实现的是:如果当前缓存的 Holiday
对象与作为参数传递的对象具有相同的 referenceDate,return 缓存的值。我有一个特定的 class 来执行该检查。这是代码:
假期class
@AllArgsConstructor
@Getter
public class Holiday {
public LocalDate referenceDate;
public boolean isHoliday;
}
缓存服务class
@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 class
@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
还没有自动装配,是否有解决方法?
在SpEL的MethodBasedEvaluationContext
中访问方法变量,需要使用#
,但class变量不需要#
。 属性 查找将自动为没有 #
符号的 属性 找到 getter。所以,你的 SpEL 应该是
cacheService.isReferenceDateCached(#holidayDateToCheck)
如果此 SpEL 不起作用,请尝试为 cacheService
创建 getter 方法。
因为您正在使用 @Cacheable(...)
注释,Spring 将使用上下文 class MethodBasedEvaluationContext
评估该 SpEL 表达式。这会将根对象设置为 CacheExpressionRootObject
,并且将使用该根对象执行 属性 查找。
由于您试图在 bean 上引用 属性,最简单的解决方案是在 SpEL 表达式中直接引用该 bean。这是通过 @
(例如 @myBeanName
)完成的。 Spring 然后将在 ApplicationContext
中查找具有该名称的 bean。请记住,没有显式名称定义的 bean 将使用 class 名称的小驼峰命名。例如,名称为 MyBeanName
的 class 的 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
}
尝试
@Cacheable(value = "holiday", key = "holidaycheck", condition = "#{cacheService.isReferenceDateCached(#holidayDateToCheck)}")
public Holiday isHoliday(final LocalDate holidayDateToCheck) {
//some code to call a rest api
}