简体   繁体   English

Spring 缓存特定值@Cacheable注解

[英]Spring cache for specific values @Cacheable annotation

I want to cache a result of a method only when the attribute of the result contains specific values.我只想在结果的属性包含特定值时才缓存方法的结果。 For example例如

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)
}

In the above method, I want to cache the response only when Response.Success.data.code == (long list of codes).在上述方法中,我只想在 Response.Success.data.code ==(长代码列表)时缓存响应。 Please note, in the previous line data is nothing but APIOutput object.请注意,上一行中的数据只不过是 APIOutput object。 How could I achieve it using unless or any other approach.我如何使用除非或任何其他方法来实现它。 I was thinking of writing a function that takes a doApicall method result as input and would return true or false and call that method it as unless="call a method".我正在考虑编写一个 function ,它将doApicall方法结果作为输入,并返回 true 或 false 并将该方法称为除非 =“调用方法”。 But I'm not sure how to do it.但我不知道该怎么做。 Any help is highly appreciated.非常感谢任何帮助。

You can specify an expression to be evaluated in unless using SpEL . unless使用SpEL ,否则您可以指定要评估的表达式。 The returned value is available as result so you can do something like -返回的值作为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)
}

You can even use Regex in SpEL and can create custom Expression parsers if the existing functionality is not enough for your usecase.如果现有功能不足以满足您的用例,您甚至可以在 SpEL 中使用 Regex,并且可以创建自定义表达式解析器。

Thanks Yatharth and John.感谢 Yatharth 和约翰。 Below is the condition that worked for me.以下是对我有用的条件。 resultcodes in the below expression is a list以下表达式中的结果代码是一个列表

@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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM