SpringCache源码简单研究

最近目标是写一个只需要本地的缓存,并且可以设置过期时间。
经过了解呢,spring有自带的缓存springcache,了解了一下发现使用是挺方便的,老早之前整合redis的时候还使用过。但是未能满足业务需求的是,无法设定过期时间。
那就准备自己实现一下子呢。

了解到,有两个玩意,CacheManager和Cache两个ConcurrentMap,前者用来管理cache的,可以通过name获取cache,后边是保存缓存内容,通过key获取缓存值。

而我的需求的过期时间细粒度并不高,相同name空间定时清空就可以了,因此只用重新实现CacheManage就可以了。
然后感觉还是心里不踏实,寻思还是看看源码吧,缕一缕实现流程,看看咱这思路有错没。

AOP拦截方法

SpringAOP实现的CacheInterceptor对添加缓存注解的方法进行了拦截,所以这里就是咱分析的入口啦。
SpringCache源码简单研究

发现里面的实现是调用execute方法,显而易见是实现在父类CacheAspectSupport里面的,咱接着看:
SpringCache源码简单研究
可以嘛,十分简短。。
首先是getCacheOperations()

getCacheOperations

getCacheOperations()获取的是CacheOperation对象列表,也就是CachePutOperation、CacheableOperation、CacheEvictOperation分别对应集中注解的实体类,并且是这里是有缓存的,有就直接获取,没有就创建再返回.

然后分析其获取过程,一路找下来终于发现了咱定义的注解为何能联系起来了。
在SpringCacheAnnotationParser的parseCacheAnnotations()方法中,去匹配Cacheable\CacheEvict\Cacheput\Caching等注解类型,构造相应对象。构造的CacheOperation就像个实体类了,里面装有cacheNames\key\cacheManager\cacheResolver等信息了,终于联系起来了。

完事如果获取到了CacheOperations就会调用咱私有的execute,感觉是重点来了。

私有execute

SpringCache源码简单研究
方法里面注解挺详细的,确实是在实现业务操作了,也就是咱的取缓存、放缓存等。

问题出现,流程都走完了,咱们说了半天,发现整个流程好像没咋出现之前了解到的CacheManager和Cache呢,所以还是再把目标瞄准上面私有的excute方法里面,进一步剖析,看看【从缓存取】是怎么一个样子。

上面提到咱获取到了cacheOperations集合,但是其类型还是有好几种不好统一管理。又一看,excute的入参是一个名叫CacheOperationContexts的内部类,并且确实是由CacheOperations构造出来的,那么咱解析看看。

SpringCache源码简单研究
发现里面就两个属性context和sync,并且构造方法确实是对通过传入的cacheOperations存放进context(是一个multivalueMap),以cacheOperation的class为key,CacheOperationContext对象为值
SpringCache源码简单研究
???我看到这个值的时候蒙了,然后才发现CacheOperationContextCacheOperationContexts少了一个s,是另外一个内部类,里面存有了我们希望看到的Cache。发掘发掘这里的Cache是怎么来的呢

SpringCache源码简单研究
发现CacheOperationContext的构造方法里面cache属性是通过AbstractCacheResolver#resolveCaches来获取到的,通过调用CacheManager的getCache,好家伙太感动了,再让我看看CacheManager哪来的。

然后又让我发现:
setCacheManager是在CacheAspectSupport里面的getCacheOperationMetadata()方法里面,初始化成功之后,会从BeanFactory通过CacheManager.class的方式set好cacheManager,所以我们自定义cachemanager之后,加上@primary注解就可以产生作用了。

CacheAspectSupport类还有个CachePutRequest的内部类是用于往cache里面放key和value的
至此,cache获取到了,我的目的也达到了。

总结

1.CacheAspectSupport类的任务很重啊,里面的execute完成了缓存的业务实现。
2.这一整套流程虽然看着复杂,但根本还是Cache在完成任务,并用CacheManager来管理Cache
3.CacheManagerCache在整体流程里面的只是负责单纯的功能提供,没有去干预别的流程,所以进行改动还是没啥太大问题的。

上一篇:Apache Cloudstack Development 101 -- Data Access Layer


下一篇:常用缓存redis,springCache