在服务不可用时在春季缓存

时间:2017-11-24 22:17:10

标签: spring spring-mvc caching spring-cache

我希望在Spring中启用缓存,以便在调用外部服务时,如果没有异常发生,则返回响应并更新缓存,但仅在外部服务引发某些异常时才使用缓存中的值。 / p>

伪流程将是这样的

  try{
    response = service.externalCall(key);
    cache.update(key, response);
    return response;
  } catch (Exception e) {
    return cache.get(key);
  }

1 个答案:

答案 0 :(得分:0)

是的,如果没有对Cache的引用,你真的无法做到这一点,但你可以利用 Spring的Cache Abstraction 中的某些功能来实现你想要的。

我写了一个例子here

简而言之,此测试类演示了looking up (Randomly generated) Stock Quotes(对于VMW)。很明显,这个remote service可能并不总是可用,因此我的client需要handle这一点。

remote service模拟throwing an IllegalStateException for every even number call不可用。否则,它returns a new (randomly generated) stock quote for the ticker symbol

如果服务成功,它将update the cache(即“ StockQuotes ”)。

知道服务可能失败,client expects this and guards against it by returning the previous stock quote from the "StockQuotes" Cache。当然,为了做到这一点,它必须有一个reference to the Cache that is storing the stock quotes。在我的示例中,我使用Spring @Qualifier注释来区分可能在 Spring 上下文中注册的多个Caches,如果有多个类型为{{1的bean>声明,例如出于类似目的。如果您正在使用的缓存提供程序中没有Cache,您当然可以实现您喜欢的任何行为。

正如您所看到的,我的示例仅使用Spring's provided ConcurrentMapCacheManager caching provider。我还将"StockQuotes" cache作为 Spring 上下文中定义的bean提供给我的客户端。 Cache会自动创建“已命名的”ConcurrentMapCacheManager(如果该Cache尚未存在且ConcurrentMapCacheManager未使用现有的Cache名称显式构建。

虽然 Spring的缓存抽象并非专门用于处理您的UC,但只需以适当的方式组织您的代码,您就可以达到类似的效果。

现在,如果您有许多不同的服务需要这种类型的行为,甚至是需要的,那么您可以考虑创建一个基于 Spring 的AOP Aspect来以通用方式封装此代码组织从而允许您以统一的方式进一步扩展/装饰应用程序的缓存行为。您可以相对于缓存方面对Aspect进行排序,以便在服务不可用时正确应用逻辑。我会把这作为练习让你弄明白,但实际上并不困难。

希望这有帮助!

-John