springCache源码分析

概括

  1. springCache主要利用切面+拦截器去实现的
  2. 切面的matches方法判断是否要进行拦截
    2.1 判断依据:方法上是否有Cacheable、CacheEvict、CachePut、Caching注解
  3. 在拦截器中进行缓存相关操作

BeanFactoryCacheOperationSourceAdvisor分析

  1. 继承SpringAop的AbstractBeanFactoryPointcutAdvisor类,重写其getPointcut方法,返回CacheOperationSourcePointcut

  2. 重点关注CacheOperationSourcePointcut#matches方法
    在这里插入图片描述

    2.1 作用:判断方法是否被拦截
    2.2 在上图中发现getCacheOperationSource方法,该方法是个抽象方法,在BeanFactoryCacheOperationSourceAdvisor中初 始化CacheOperationSourcePointcut时,实现getCacheOperationSource方法 在这里插入图片描述
    2.3 而cacheOperationSource属性是通过ProxyCachingConfiguration进行配置
    在这里插入图片描述
    在这里插入图片描述
    2.4 AnnotationCacheOperationSource空构造方法,会默认publicMethodsOnly=true,annotationParsers为单个SpringCacheAnnotationParser 在这里插入图片描述

方法是否被拦截的判断AnnotationCacheOperationSource#getCacheOperations

  1. 判断依据:方法
  2. 将方法以及调用类封装new MethodClassKey(method, targetClass),成为缓存的Key
  3. 解析目标类方法上的缓存注解
    在这里插入图片描述
    3.1 Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
    3.2 SpringCacheAnnotationParser#parseCacheAnnotations解析方法的缓存注解
    在这里插入图片描述

拦截器CacheInterceptor分析

  1. 作用:缓存是否命中直接返回+查询结果缓存
  2. CacheInterceptor实现CacheInterceptor接口,实现invoke方法(拦截方法)
    在这里插入图片描述

CacheAspectSupport#execute分析

  1. 获取CacheOperationSource
    1.1 而拦截器的CacheOperationSource是通过配置得到 在这里插入图片描述
    1.2 在切面的matches方法判断时,将缓存注解解析结果存放在attributeCache中
  2. 根据key获取缓存操作类CacheOperation集合

缓存操作

在这里插入图片描述

  1. 处理任何早期驱逐(待分析)
  2. 检查是否有匹配条件的缓存项
    2.1 缓存命中,直接返回缓存
    2.2 没有命中,则添加CacheableOperation请求
  3. 添加显示的增加缓存请求CachePutOperation
  4. 遍历请求集合,调用其apply方法
  5. 处理任何延迟的收回
查看缓存是否命中
  1. 生成缓存key:CacheAspectSupport#generateKey
    在这里插入图片描述
    1.1 从上图可以得知,key和keyGenerator参数是一个互斥操作
    1.2 SimpleKeyGenerator#generateKey生成缓存key(keyGenerator分析见下方getCacheOperationMetadata分析)
    在这里插入图片描述
  2. 根据key查询缓存CacheAspectSupport#findInCaches
    在这里插入图片描述
    2.1 context的caches属性的初始化(见下方getCaches分析)
    2.2 CompositeCache#get组合缓存中获取指定缓存
    (1)从本地缓存获取,如果命中则直接返回
    (2)从远程缓存获取,如果命中,则先放入本地缓存,然后再返回
CacheAspectSupport#getCacheOperationMetadata
  1. 获取keyGenerator
    1.1 如果key生成器keyGenerator为空,则getKeyGenerator方法默认生成(SingletonSupplier#obtain->SimpleKeyGenerator)
    1.2 如果keyGenerator不为空,则根据beanName获取KeyGenerator的实现类
  2. 获取CacheResolver
    2.1 通过cacheResolver属性在Spring容器中按照beanName获取CacheResolver实现类
    2.2 通过cacheManager属性获取CacheManager实现类,将其封装成SimpleCacheResolver
    2.3 兜底方案:operationCacheResolver = getCacheResolver();//默认
CacheAspectSupport#getCaches
  1. Collection<? extends Cache> caches = cacheResolver.resolveCaches(context);
  2. cacheResolver是如何初始化的?
    2.1 CacheInterceptor实现了SmartInitializingSingleton接口,在afterSingletonsInstantiated方法中进行初始化
    在这里插入图片描述
    2.2 从Spring容器中获取CacheManager的实现类:CompositeCacheManager(自定义)
    2.3 this.cacheResolver = SingletonSupplier.of(new SimpleCacheResolver(cacheManager));
  3. 在CacheOperationContext构造方法中this.caches = CacheAspectSupport.this.getCaches(this, metadata.cacheResolver);

后续

  1. 具体的缓存注解解析待分析
  2. 缓存操作只分析一小部分(缓存是否命中)
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cache 中,我们可以通过使用注解来声明缓存操作。例如,@Cacheable 注解用于表示方法的结果应该被缓存,@CacheEvict 注解用于表示缓存应该被清除,@CachePut 注解用于表示方法的结果应该被缓存,等等。这些注解都是在运行时被解析的,Spring 通过解析这些注解来确定缓存操作应该被执行的方式。 在 Spring 中,注解解析器是用于解析注解的组件。在 Spring Cache 中,注解解析器的作用是解析 @Cacheable、@CachePut、@CacheEvict 和 @Caching 注解,并将它们转换为缓存操作的定义。Spring Cache 提供了 AnnotationCacheOperationSource 类来实现这个功能。 AnnotationCacheOperationSource 类实现了 CacheOperationSource 接口,它的主要作用是解析注解并返回缓存操作的定义。在 Spring Cache 中,每个缓存操作的定义都表示为一个 CacheOperation 对象。AnnotationCacheOperationSource 类的 getCacheOperations() 方法返回一个 List<CacheOperation> 对象,表示指定方法上的所有缓存操作的定义。 AnnotationCacheOperationSource 类的核心方法是 buildCacheOperations() 方法。这个方法接收一个 MethodInvocation 对象,它描述了要执行的方法及其参数。buildCacheOperations() 方法首先检查给定的方法是否具有 @Cacheable、@CachePut、@CacheEvict 或 @Caching 注解。如果有这些注解,它将解析它们并返回一个包含缓存操作定义的 List<CacheOperation> 对象。如果没有这些注解,它将返回一个空的 List<CacheOperation> 对象。 解析注解的过程非常复杂,AnnotationCacheOperationSource 类使用了多个辅助类来完成这个过程。这些辅助类包括 AnnotationCacheAspect、CacheAnnotationParser、CacheAnnotationParserUtils 和 CacheAspectSupport。AnnotationCacheAspect 是一个切面,它拦截所有具有 @Cacheable、@CachePut、@CacheEvict 或 @Caching 注解的方法。CacheAnnotationParser 类用于解析注解并返回相应的缓存操作定义。CacheAnnotationParserUtils 类包含一些通用的注解解析方法。CacheAspectSupport 类是一个抽象类,它提供了一些通用的缓存操作方法,它的子类可以继承这些方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值