Spring 为特定值缓存 @Cacheable 注解

Spring cache for specific values @Cacheable annotation

我只想在结果的属性包含特定值时才缓存方法的结果。例如

Class APIOutput(code: Int, message: String)
sealed class Response<out T : Any> : Serializable {
    data class Success<out T : Any>(val data: T) : Response<T>()
    data class Error(val errorText: String, val errorCode: Int) : Response<Nothing>()
}
@Cacheable(
        key = "api-key",
        unless = "do something here"
    )
fun doApicall(uniqueId: Long): Response<APIOutput> {
        //make API call
        val output = callAPI(uniqueId)
        return Response.Success(output)
}

在上面的方法中,我只想在Response.Success.data.code ==(长代码列表)时缓存响应。 请注意,在上一行中 data 只是 APIOutput 对象。我怎么能使用 unless 或任何其他方法来实现它。我正在考虑编写一个函数,该函数将 doApicall 方法结果作为输入,并将 return true 或 false 并将该方法称为 unless="call a method"。但我不确定该怎么做。非常感谢任何帮助。

您可以使用 SpEL 指定要在 unless 中求值的表达式。返回值可作为 result 使用,因此您可以执行类似 -

的操作
@Cacheable(
        key = "api-key",
        unless = "#result!=null or #result.success.data.code!=200"
    )
fun doApicall(uniqueId: Long): Response<APIOutput> {
        //make API call
        val output = callAPI(uniqueId)
        return Response.Success(output)
}

您甚至可以在 SpEL 中使用正则表达式,如果现有功能不足以满足您的用例,您还可以创建自定义表达式解析器。

谢谢 Yatharth 和 John!以下是对我有用的条件。 resultcodes 下面的表达式是一个列表

@Cacheable(
            key = "api-key",
            unless = "!(#result instanceof T(com.abc.Response$Success)) 
            or (#result instanceof T(com.abc.Response$Success) 
            and !(T(com.abc.APIStatus).resultCodes.contains(#result.data.code)))"
)
fun doApicall(uniqueId: Long): Response<APIOutput> {
    //make API call
    val output = callAPI(uniqueId)
    return Response.Success(output)
}