【问题标题】:Spring Cache - How can I catch an exception in unless argument?Spring Cache - 我如何在除非参数中捕获异常?
【发布时间】:2018-10-15 02:09:22
【问题描述】:

我得到以下代码:

@Cacheable(value = "cacheName", key = "#someMap.toString()", unless="#result.error")
public List<Book> methodName(Map<Integer, Integer> someMap) throws BookException {
//...

该方法抛出 BookException 并且我想避免在发生这种情况时缓存结果。但是当我执行该方法时:

org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'error' cannot be found on object of type 'java.util.ArrayList' - maybe not public?

【问题讨论】:

    标签: java spring ehcache spring-el spring-cache


    【解决方案1】:

    如果在带注释的方法中抛出异常并进一步传播(似乎是您的情况),您不必捕获它。在这种情况下,没有键值对存储在缓存中,因此默认情况下您可以获得所需的行为:)

    简而言之:删除“除非”条件并享受。

    【讨论】:

      【解决方案2】:

      由于结果是一个集合(在本例中是一个列表),因此您只能使用附加到该类的操作。所以,你可以说类似unless="#result != null"unless="#result.size() &gt; 0"

      错误不是List 类中的有效方法。

      【讨论】:

      • 好的,假设我删除了除非。如果出现异常,@Cacheble 不会将错误保存到缓存中吗? (顺便谢谢)。
      • @tristobal 它将为 cacheName 存储一个null,您不希望这样,但它应该在其他时间尝试。否则,您将继续为同一请求获得null,直到不再存储缓存值(保留超时)。因此,如果您知道您的方法可能会返回 null 或抛出异常,请使用 unless
      • 那么,unless = "#result == null" 应该在出现异常时完成这项工作?
      • @BabajideM.Moibi 你用错了unless。应该是#result == null || #result.size() == 0。你想缓存除非结果是空的,在这种情况下你不需要。
      【解决方案3】:

      让我们试试这个配置,当异常发生时它不会缓存数据:

      @Cacheable(value = "sendAndReceiveMessage", key = "{#requestData.toString()}", unless = "#result instanceof T(java.lang.Exception)")

      【讨论】:

      • 我已经用@Cacheable 进行了测试,如果发生异常,它将返回异常类,所以我们不能在这里检查 null 或 not null。
      • 除非方法完成时执行块。它将包含该调用的完整信息:输入是什么,结果是什么。
      • 对于条件,它只是方法运行前输入和执行的信息。所以它不会有关于结果的信息。
      【解决方案4】:

      不要抛出异常。而是使用 try/catch 块并在 catch 块中,将空值分配给列表。也使用@Cacheable(value = "cacheName", key = "#someMap.toString()", unless="#result==null")。这个技巧适用于所有对象,包括集合。

      【讨论】:

        猜你喜欢
        • 2018-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        • 2014-12-26
        • 1970-01-01
        • 2019-04-17
        • 2018-09-02
        相关资源
        最近更新 更多