Springboot中的缓存Cache和CacheManager原理介绍
背景理解
什么是缓存,为什么要用缓存
程序运行中,在内存保持一定时间不变的数据就是缓存。简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了
所以缓存并不是什么高大上的技术,只是个概念,把要多次使用的东西存在一个变量里,时不时取出来使用,就达到了缓存的目的,缓存就是存放数据的容器
那为什么要用缓存呢,是因为要多次使用。一个程序总有一些数据时可预见被多次使用(预见的准不准就是常说的命中率)
比如一个复杂的计算结果,一次数据库访问取得的数据等耗时耗资源的数据就能放入缓存,目的就是为了节省开销,我们要用有限的资源(CPU,内存,带宽等等)尽量做最多的事情。
为什么要用SpringCache(缓存的演变过程)
缓存的思考
如果我们要设计一个缓存,最基本的功能是存和取:
1.能在缓存里存放数据
2.能在缓存里取出数据
可是这不够呀,比如以下的思考
1.取数据时判断,数据是否存在,如果不存在是不是要数据库取
2.如果是过期的内容是不是要更新
3.如果我有多个缓存,一个是我自己设计的HashMap缓存,一个是名声很大的redis,还有....,那需要个缓存管理器呀
为了让缓存更好用,更“智能”,越来越多的需求就会被提出来,而缓存就是这样一步步演变直到SpringCache横空出世,功能十分强大(说白了就是我们少写很多代码)
SpringCache的好处
SpringCache包含两个顶级接口,Cache(缓存)和CacheManager(缓存管理器),顾名思义,用CacheManager去管理一堆Cache。
最最关键的地方:抱紧了Spring的大腿,可以使用注解就能完成数据进入缓存!!
给大家举个例子,就知道多简单了
首先,Springboot中会自动加载一个CacheManager(它有默认的实现类),所以只要写好一个自定义的Cache即可(如果想用系统定义好的或者第三方如RedisCache也行,记得向Spring注册这个bean即可)
@Component
public class MyCache implements Cache {
/*
实现接口方法,一些关于数据set和get的方法
CacheManager是根据Cache的名字进行管理的
所以假设这个Cache名为MyCache
*/
}
然后在得出数据的方法上写上注释即可
@Cacheable(value = "MyCache",key = "#id")
public String getNavegationURLs(String id) {
//一个获取数据的方法
}
这样就会在调用这个方法时,会以id为key值,在名为MyCache的Cache容器中查找(注解中value就是缓存名字,不同名字指定使用不同的缓存)
如果没查到,则执行方法 getNavegationURLs,将返回值存入缓存
如果找到了,就直接将从缓存取值,直接返回,不用执行方法 getNavegationURLs
还有其他方便的Cache注解自行百度,重要的是我们根本不用写任何关于调用缓存的逻辑代码,只用关注于缓存自身的逻辑
注解如何起作用的,源码流程大致了解
为什么要了解源码
最直接的原因是因为SpringCache是不支持灵活的缓存时间设置的,所以想了解大概的来龙去脉去实现一个支持缓存过期时间设置和自动更新的类(之后会写实现博文)。
高大上的原因是想通过这次探索,去了解下Spring对类的管理机制,去接触下AOP的实现
SpringCache源码简单分析
大家从上面例子有没发现问题,Cache和CacheManager是怎样做关联的,其实是Spring扫包实现的
凡是继承了Cache接口的类,都会被自动注入进CacheManager中,最终存储于CacheManager的实现类中

接着会生成被@Cacheable(或者其他SpringCache注解修饰过)的代理类,并会将管理它的CacheManager赋值进去

看这段代码,就知道如果要设置多个CacheManager,就得在众多实现类的其中一个加上@Primary,不然会Spring会报错能选择的Bean太多而不知道用哪个
代理类生成后(包括会根据不同的注解生成信息类CacheOperationMetadata,到时候就会根据这个类的内容进行缓存操作,说白了就是调用我们实现Cache里面的各种方法)
Springboot底层初始化完成后,进入我们写的代码逻辑
如果这时进入了该类的方法,如:

代码跟进去,你会神奇的发现进入了代理类的intercept方法,怎么进去的呢~(具体原理看下面3.0)

这里面就会根据注解类型,进行缓存的逻辑判断,然后决定会不会调用我们写的方法~
代理类原理介绍(AOP切面之类的都是通过代理哦)
Spring代理分为两种:
1.JDK原生动态代理,要求被代理的类需要实现接口(通过接口来实现的代理)
那么代理类满足以下条件:


具体内容可以参考这篇精品博客:https://www.cnblogs.com/CarpenterLee/p/8241042.html
如果你想自己实现代理类(就是不喜欢用工具包),其实也行啊,输出符合class规范的二进制字节码就行啦~~~(认真学习JVM规范吧)
至此,该分享的就分享完啦,有什么问题欢迎留言一起探讨~
Springboot中的缓存Cache和CacheManager原理介绍的更多相关文章
- Springboot中使用缓存
在开发中,如果相同的查询条件去频繁查询数据库, 是不是会给数据库带来很大的压力呢?因此,我们需要对查询出来的数据进行缓存,这样客户端只需要从数据库查询一次数据,然后会放入缓存中,以后再次查询时可以从缓 ...
- SpringBoot中Shiro缓存使用Redis、Ehcache
在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...
- SpringBoot(七) SpringBoot中的缓存机制
随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...
- Java 中常用缓存Cache机制的实现
所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 所谓缓存,就是将程序或系统经常要调用的对象存在内存中 ...
- Java 中常用缓存Cache机制的实现《二》
所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. AD: Cache 所谓缓存,就是将程序或系统经常要 ...
- Java中常用缓存Cache机制的实现
缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例. 这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件 ...
- 缓存架构中的服务详解!SpringBoot中二级缓存服务的实现
创建缓存服务 创建缓存服务接口项目 创建myshop-service-redis-api项目,该项目只负责定义接口 创建项目的pom.xml: <?xml version="1.0&q ...
- HTTP请求中的缓存(cache)机制
http://www.chaorenmao.com/blog/?p=79 流程 当资源第一次被访问的时候,HTTP头部如下 (Request-Line) GET /a.html HTTP/1.1Ho ...
- Asp.net中使用缓存(cache)
做了一个时间优化的项目,目的就是缩短程序过程中的时间花费,最后发现了asp.net和asp.net core 中都有缓存工具来进行缓存,以加快访问速度. 找了官方demo来进行分析: ObjectCa ...
随机推荐
- LeetCode_933-Number of Recent Calls
求最近3000毫秒内有多少次调用请求,每一次ping的时间一定比上一次的时间高:解法可以判断最后面一个数t1与最前一个数t2的差不大于3000毫秒,如果大于就直接舍弃,t1与t2之间的个数就是请求次数 ...
- 记录一次Metaspace扩容引发FGC的调优总结
开始之前 在开始之前先记录一个我碰到的jvm调优的坑.那就是… 为啥我配置到idea64exe.vmoptions中的参数没有生效??? 由于之前一直是在mac上开发,本地开发时当需要优化jvm参数的 ...
- 合并果子(STL优先队列)
STL优先队列:priority_queue 定义:priority_queue<int>q; 从小到大:priority_queue<int,vector<int>,g ...
- 机器学习中梯度下降法原理及用其解决线性回归问题的C语言实现
本文讲梯度下降(Gradient Descent)前先看看利用梯度下降法进行监督学习(例如分类.回归等)的一般步骤: 1, 定义损失函数(Loss Function) 2, 信息流forward pr ...
- 清理 Sketch缓存 Storyist 3.5.1中文破解版 for Mac
Sketch这款软件可以用来做原型和UI设计,很多设计师和产品经理都在用,时间长了以后,Sketch会占据不少缓存空间,这时候可以试试 Sketch Cache Cleaner 这款软件清理历史文件和 ...
- .Net Core3.0使用gRPC
gRPC是什么 gRPC是可以在任何环境中运行的现代开源高性能RPC框架.它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证.它也适用于分布式 ...
- postman使用实例
以下以一个登录接口为例,介绍一下postman是如何发请求的. 先执行Pre-request Scripts(预处理) - body - tests(进行断言) postman中变量的引用: {{}}
- unittest断言
assertEquals(expected,actual,msg=msg) # 判断 expected,actual是否一致,msg类似备注,可以为空
- 图论-最小生成树<Kruskal>
昨天: 图论-最小生成树<Dijkstra,Floyd> 以上是昨天的Blog,有需要者请先阅读完以上再阅读今天的Blog. 可能今天的有点乱,好好理理,认真看完相信你会懂得 然而,文中提 ...
- 学习笔记:flutter项目搭建(mac版)
什么是flutter Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的 ...