Springboot注解式缓存原理详解


我们这里以redis作为缓存载体为例,在Springboot里使用redis缓存时只需要需要简单几步配置就可以:
1、引入 spring-boot-starter-data-redis依赖和配置
2、在Springboot启动类上加上@EnableCaching 注解
3、根据实际的缓存场景,在需要缓存的方法上加上相应的注解(@Cacheable、@CachePut、@CacheEvict等)

这样就可以使用redis缓存了,那么这背后的原理是什么,Springboot是怎么实现的?
Springboot在背后实际做了两件事:
1、根据特定的注解来识别出需要使用缓存的方法并生成动态代理类,加入对缓存的增删改查的切面逻辑
2、根据配置选择缓存的载体,这篇文章以redis作为缓存载体为例
下面看下Springboot是怎么实现这两件事的

生成动态代理类

Spring在生成动态代理类的过程中,抽象了几个重要的参与者:
1、InfrastructureAdvisorAutoProxyCreator:负责生成动态代理类,该类根据注册到容器内的Advisor、Pointcut、Advice来匹配需要增强的类并生成动态代理类
2、Pointcut:指定在什么地方加入切面逻辑,在这里就是被@Cacheable、@CachePut、@CacheEvict等注解标注的方法
3、Advice:要做哪些增强逻辑,这里就是根据具体注解对缓存做增删改查的逻辑
4、Advisor:封装了 PointcutAdvice

总结一句话就是要告诉Spring容器在什么地方做哪些增强逻辑,下面看下这几个重要参与者是怎么注入到Spring容器的

InfrastructureAdvisorAutoProxyCreator

注册过程

@EnableCaching注解上有个@Import注解,该注解上importCachingConfigurationSelector类,@Import注解告诉Springboot需要引入这个bean,该类可以说是总入口,负责向Spring容器注入
上面提到的InfrastructureAdvisorAutoProxyCreator、Advisor、Pointcut、Advice,核心逻辑在selectImports方法里
在这里插入图片描述

这里会根据配置选择是使用PROXY模式还是ASPECTJ模式,这是两种生成动态代理的技术实现,默认是PROXY,这里会向容器注册AutoProxyRegistrarProxyCachingConfiguration两个bean,而在 AutoProxyRegistrar 类(该类实现了ImportBeanDefinitionRegistrar接口,属于Springboot的向容器注入bean的一种扩展机制)里会向Spring容器注册InfrastructureAdvisorAutoProxyCreator

动态代理类生成逻辑

在这里插入图片描述

InfrastructureAdvisorAutoProxyCreator类实现了BeanPostProcessor接口,父类AbstractAutoProxyCreator实现了postProcessAfterInitialization方法,该方法会在bean的init方法执行后被Spring容器回调,遍历Spring容器里的Advisor,如果Pointcut匹配成功,则进行Advice增强。

在这里插入图片描述

在这里插入图片描述

在Bean生成过程中会有很多这种后置处理器,Spring容器会在每个时间点回调这些后置处理器:
在这里插入图片描述

Advisor、Pointcut、Advice

上面讲到的InfrastructureAdvisorAutoProxyCreator会根据容器内的Advisor、Pointcut、Advice来生成动态代理类,这里看下Springboot是怎么向容器注册这三个bean的,前面讲到@EnableCaching注解上有个@Import注解,该注解上importCachingConfigurationSelector类,该类向容器注册AutoProxyRegistrarProxyCachingConfiguration两个bean,而ProxyCachingConfiguration负责向容器注入Advisor、Pointcut、Advice
在这里插入图片描述

可以看到这个类会注册BeanFactoryCacheOperationSourceAdvisor,该类实现PointcutAdvisor接口,用来返回Pointcut,类图如下:
在这里插入图片描述

CacheOperationSource类负责告诉容器哪些类和方法需要增强,实际是Pointcut的实现
在这里插入图片描述

CacheInterceptor就是具体的增强逻辑了,在这里会根据具体方法上的注解来判断需要做哪些切面逻辑,详细细节可以自己debug
在这里插入图片描述

到这里可以看到用来生成动态代理类的几个元素都有了

选择缓存载体

缓存总是要有个载体的,这里以redis为例,在我们引入redis依赖后,Springboot是怎么知道用redis来存放缓存的?
这里涉及到Springboot的自动装载机制了,总结一句话就是Springboot在启动过程中会扫描META-INF/spring.factories下的EnableAutoConfiguration所指向的所有需要自动装载的类,
其中就有CacheAutoConfiguration,该类会import CacheConfigurationImportSelector
在这里插入图片描述

CacheConfigurationImportSelector类会告诉Spring容器加载哪些CacheManager,其中就包括redisCacheManager
在这里插入图片描述
在这里插入图片描述

而在RedisCacheConfiguration类里会加载RedisCacheManager
在这里插入图片描述
这里主要上面的几个条件注解,其中当我们引入了redis的依赖后,就会满足上面的条件,所以如果没有引入redis依赖,那么也就不会注册RedisCacheManager,该类实现了CacheManager
在这里插入图片描述

Cache里就是对缓存的怎删改查接口
在这里插入图片描述

到这里也弄清楚了Springboot怎么选择CacheManager,还有最后一个问题就是上面的切面逻辑是怎么获取到CacheManager的?

在这里插入图片描述

在前面讲到的CacheInterceptor类的afterSingletonsInstantiated方法里会遍历注册到容器内的CacheManager,这个方法会在bean完成实例化和依赖注入后被容器回调。
到这里核心的步骤都已经讲到,细节需要自己去debug了

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过使用注解来简化开发过程,提供了一种快速、方便的方式来配置和管理Spring应用程序。 在Spring Boot注解被广泛应用于各个方面,包括配置、依赖注入、AOP等。下面是一些常用的Spring Boot注解及其底层原理: 1. @SpringBootApplication:这是一个组合注解,包含了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。@Configuration用于定义配置类,@EnableAutoConfiguration用于自动配置Spring应用程序上下文,@ComponentScan用于扫描并加载标有@Component注解的类。 2. @RestController:这个注解用于标识一个类是RESTful风格的控制器,它将类方法返回的数据直接以JSON或XML格发送给客户端。 3. @RequestMapping:这个注解用于映射HTTP请求到控制器的处理方法上。可以通过指定URL路径、请求方法、请求参数等来定义具体的映射规则。 4. @Autowired:这个注解用于自动装配依赖对象。Spring Boot会根据类型进行自动查找并注入相应的实例。 5. @Value:这个注解用于从配置文件读取属性值,并将其注入到对应的字段或方法参数。 6. @Component:这个注解用于标识一个类是Spring组件,会被自动扫描并加载到Spring容器。 7. @ConfigurationProperties:这个注解用于将配置文件的属性值绑定到一个Java对象上,可以通过@ConfigurationProperties(prefix = "prefix")指定属性的前缀。 以上是一些常用的Spring Boot注解及其底层原理。通过使用这些注解,可以简化开发过程,提高开发效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值