【RuoYi-Vue-Plus】学习笔记 32 - Redisson(七)集成 Spring Cache 缓存分析

前言

先说句题外话,框架发布了 V4.3.0 公测版本 了,有兴趣的朋友可以去尝鲜。

最近没有更新不是在摆烂,而是在梳理 AOP 的相关内容,因为这篇博客的内容属实有点难搞,所以就去找了很多书籍、博客和视频去恶补相关的内容(其中有些很好的我会在下面的参考目录里面一一列举出来)。

这篇博客可能更多的是偏向于个人学习的笔记,所以如果有错漏的地方烦请指正。

参考目录

Redisson 缓存是整合了 Spring Cache,而 Spring Cache 的实现又是基于 Spring AOP 的,因此个人觉得对于这一部分的学习需要夯实基础才能更好地学习和理解。

框架集成

1、Maven

总工程 pom.xml,Redisson 版本 V3.17.5
总工程 pom.xml
公共模块 pom.xml
公共模块 pom.xml

2、配置文件缓存配置

配置文件 application.yml
配置文件 application.yml

3、Redis配置类

com.ruoyi.framework.config.RedisConfig
Redis配置类 RedisConfig
其中,注解 @EnableCaching 开启缓存功能。

Spring Cache 配置 RedisConfig#cacheManager
Redis配置类 Spring Cache 配置
(红线告警无视即可,在 RedissonAutoConfiguration 自动装配时已经在容器中注入了 RedissonClient

4、缓存测试类

com.ruoyi.demo.controller.RedisCacheController
缓存测试类 RedisCacheController
该类提供了三个主要缓存注解的演示 Demo 以及说明:

注解解析使用注意事项
@Cacheable表示这个方法有了缓存的功能,方法的返回值会被缓存下来。下一次调用该方法前,会去检查是否缓存中已经有值:如果有就直接返回,不调用方法;如果没有,就调用方法,然后把结果缓存起来。一般用在查询方法上缓存注解严禁与其他筛选数据功能一起使用。例如: 数据权限注解会造成 缓存击穿数据不一致 问题
@CachePut会把方法的返回值put到缓存里面缓存起来,供其它地方使用通常用在新增方法上
@CacheEvict清空指定缓存一般用在更新或者删除的方法上

5、测试

5.1、@Cacheable

请求参数
Redis保存结果

5.2、@CachePut

请求参数
Redis保存结果
修改后 @Cacheable 接口请求结果:
请求结果

5.3、@CacheEvict

请求参数
Redis保存结果
test 已被删除。

源码分析

在开始之前,我想先声明一下,最好是对于 Spring AOP 有一定程度的了解,知道什么是 PointcutPointcutAdvisorAdviceMethodInterceptor 等。除此之外,了解 Spring AOP 的基本实现原理,否则看起来可能会比较费解(本文不会太详细去阐述相关概念,可以通过参考目录或者其他资料自行补充理解)。

1、Redisson 整合 Spring Cache 核心 API

先放一张简单的脑图,只是列举出了 Spring Cache 比较核心的 API:
Spring Cache 核心 API

2、缓存自动装配

先来简单看下自动装配。

在配置文件 application.yml 中,打开 debug 配置:

debug: true

启动服务观察控制台输出。

2.1、CacheAutoConfiguration

在这里插入图片描述
在这里插入图片描述
这里的 CacheManager 正是 RedisConfig 中配置的缓存管理器:
在这里插入图片描述

2.2、RedissonCacheStatisticsAutoConfiguration

在这里插入图片描述
在这里插入图片描述

2.3、CacheMetricsAutoConfiguration

在这里插入图片描述
在这里插入图片描述
这里引入了 CacheMetricsRegistrarConfiguration
在这里插入图片描述
该方法会绑定缓存管理器到注册表中:
在这里插入图片描述
通过 RedissonSpringCacheManager 获取 Cache:
在这里插入图片描述
RedissonSpringCacheManager#createMapCache
在这里插入图片描述
RedissonSpringCacheManager#getMapCache
在这里插入图片描述
Redisson#getMapCache
在这里插入图片描述
最终得到的结果:
在这里插入图片描述

3、@EnableCaching

首先从入口开始入手,参考 叔牙 - Spring cache原理详解 中的时序图:

Spring Cache时序图

org.springframework.cache.annotation.EnableCaching
@EnableCaching
要了解一个 EnableXX 注解干了啥,就看它导入 @Import 了什么内容。

3.1、CachingConfigurationSelector

org.springframework.cache.annotation.CachingConfigurationSelector
CachingConfigurationSelector
在这里插入图片描述

3.1.1、自动代理注册器 AutoProxyRegistrar

org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions
在这里插入图片描述
org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
在这里插入图片描述

3.1.2*、代理缓存配置 ProxyCachingConfiguration

org.springframework.cache.annotation.ProxyCachingConfiguration
ProxyCachingConfiguration
最重要的配置类之一,这里面配置了缓存相关的内容,也是基于 AOP 相关的实现。下面一个个来说明。

3.1.2.1、PointcutAdvisorBeanFactoryCacheOperationSourceAdvisor

在这里插入图片描述
首先来看下 UML 图:
在这里插入图片描述
PointcutAdvisor 相当于 PointcutAdvice 的连接器( PointcutAdvisor 继承自 AdvisorAdvisorAdvice 的容器接口,他们是一对一关联的)。

3.1.2.2、CacheOperationSource

在这里插入图片描述
该方法 new AnnotationCacheOperationSource()
在这里插入图片描述
初始化了 Spring 缓存解析器 SpringCacheAnnotationParser
在这里插入图片描述
在方法 SpringCacheAnnotationParser#parseCacheAnnotations 进行缓存注解的解析操作:
在这里插入图片描述

3.1.2.3、AdviceMethodInterceptor):CacheInterceptor

在这里插入图片描述
熟悉 Spring AOP 的朋友都知道,Spring AOP 中提供了不同类型的 Advice,但是通过查看源码 AdvisorAdapter 可知,所有 Advice 底层实现都是用MethodInterceptor 来进行实现的。

查看 CacheInterceptor 的 UML 图:
在这里插入图片描述
AspectJ 实现是通过拦截器反射(invoke)来实现的,因此在该类中也必然有 invoke 方法:
在这里插入图片描述
CacheInterceptor 的能力来自于父类 CacheAspectSupport
在这里插入图片描述
稍后断点再进行说明。

4、缓存以及获取值(@Cacheable)

4.1、第一次请求,没有缓存值

CacheAspectSupport#execute
在这里插入图片描述

4.1.1、从缓存中查找是否有值

CacheAspectSupport#execute
在这里插入图片描述
CacheAspectSupport#findCachedItem
在这里插入图片描述
CacheAspectSupport#findInCaches
在这里插入图片描述
AbstractCacheInvoker#doGet
在这里插入图片描述
RedissonCache#get
在这里插入图片描述
第一次请求为空,回到主方法 CacheAspectSupport#execute,将结果进行缓存。

4.1.2、缓存

在这里插入图片描述
CachePutRequest#apply
在这里插入图片描述
AbstractCacheInvoker#doPut
在这里插入图片描述
缓存完成回到主方法,返回最终执行结果:
在这里插入图片描述

4.2、第二次请求,有缓存值

RedissonCache#get
在这里插入图片描述
获取到缓存值,直接返回到前端,不再进入请求方法体内。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MichelleChung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值