SpringCache - 请求级别缓存的简易实现

本文探讨了在SpringCache中实现请求级别缓存的解决方案,针对Web和RPC框架环境进行了分析,并详细介绍了如何扩展SpringCache,利用ThreadLocal存储和清理缓存。文章还讨论了@Cacheable的sync属性与缓存同步的关系,以及如何处理包含异步操作的请求。
摘要由CSDN通过智能技术生成

前言

SpringCache缓存初探中我们研究了如何利用spring cache已有的几种实现快速地满足我们对于缓存的需求。这一次我们有了新的更个性化的需求,想在一个请求的生命周期里实现缓存

需求背景是:一次数据的组装需要调用多个方法,然而在这多个方法里又会调用同一个IO接口,此时多浪费了一次IO的资源。首先想到的解决方案是将这次IO接口提出来调用,然后将结果作为参数传递到多个方法中,但是这样一来,每个调用这些方法的地方都得添加额外的代码。那么第二个方案就是,我们还是分别调用,只不过将这个结果缓存起来,就像我们之前做的那样。

这时候问题来了,这个数据结果我们希望尽可能实时,即使只缓存了一秒,导致在不同的请求里用了同一份数据也不太好。看来不得不自己实现一个只保持在一次请求过程中的缓存了。

方案分析

要将数据缓存在一次请求周期内,那我们先得区分是什么环境下的请求,以分析我们如何存储数据。

1. Web

Web环境下的有个绝佳的数据存储位置 HttpServletRequestAttribute 。调用setAttributegetAttribute方法就能轻易地将我们的数据用key-value的形式存储在请求上,而且每次请求都自动拥有一个干净的Request 。想要获取到HttpServletRequest 也非常简单,在web请求中随时随地调用((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest() 即可。

2. RPC框架

我司所使用的rpc框架是基于finagle自研的,对外提供服务时使用线程池进行处理请求,即对于一次完整的请求,会使用同一个线程进行处理。首先想到的办法还是改动这个rpc框架服务端,增加一个可以对外暴露的、可以key-value存储的请求上下文。为了能在方便的地方获取到这个请求上下文,得将其存储在ThreadLocal中。


综合这两种环境考虑,我们最好还是实现一个统一的方案以减少维护和开发成本。Spring的RequestContextHolder.getRequestAttributes()其实也是使用ThreadLocal来实现的,那我们可以统一将数据存到ThreadLocal<Map<Object,Object>>,自己来维护缓存的清理

存储位置有了,接下来实现SpringCache思路就比较清晰了。

实现SpringCache

要实现SpringCache需要一个CacheManager,接口定义如下

 
 
 
xxxxxxxxxx
 
 
 
 
public interf
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值