00:00
好,前面呢,我们结合看注解快速的体会了一下缓存操作,那么呢们接下来就按照这个例子,我来分析一下缓存的工作原理以及它的工作步骤。咱们这个原理呢,我们当然,哎从学了spring那么多原理,我们首先呢,就要从咱们这个自动配置类入手。然后呢,如果我们引入了缓存模块,那么缓存的自动配置就会生效,那么按照以前我们的这些自动配置的命名规则,缓存的自动配置呢,就应该叫catch什么,那应该叫catch的自动配置,诶还真有这个配置,那么这个catch auto configuration,这就是呢,代表缓存的自动配置类,那么这个自动配置类做了什么呢?它给容器中我们来看一下,给容器中呢放了一些叫。缓存管理器的一些自定义器等等等等,我们这个呢不看主要呢在这一块import给容器中呢,会导入一个叫catch configuration import select。
01:06
这个东西呢,哎,在这它呢,调用这个方法会给我们容器中导入一些缓存里边要用的组件,我们呢,就给这个方法打上断点。好,那在这打开断点呢?我们来看它给容器中导入了哪些缓存的配置组件。我们以debug模式启动起来。首先呢,我们来到第一步,诶,我们看导入了哪些呢?我们直接往下放行,我们看它返回的这个imports数据,我给这儿打一个断点,好直接放行,这imports里边呢,我们看到诶这有11条数据,STRING11,那么这11个呢,就是所有的缓存配置,哎有这么多来给大家呢复制一下。我们把这个呢,来copy y6,来复制过来,来记录在这。啊,这是我们这个缓存的。缓存的。
02:01
配置类,配置类呢,会有非常多,这是一个,哎,我们把其他的呢,我们都来记录下来。还有我们这个叫接catch,诶还有我们这个叫e h catch,诶我们通过这些命名我们就知道,哎,这是呢GSR107接catch的配置,这是如果用h catch时的一些配置,包括呢,用这些分布式的一些缓存组件,什么汉字看斯特拉,哎,咱们这in非。还有咱们这个coach base啦,包括如果你缓存用red,这也有这个配置类,还有这些他们呢,都在这个自动配置包下啊,我们这有一个缓存。有这么多的自动配置,他们呢,首先是有顺序的。这是缓存的一些配置类,那哪些配置类能生效呢?哪个配置类默认生效?因为这些配置类呢,我们来随便点进去看一个,它们都会有规则判断,哎,我们就来看它,它判断呢,如果我们容器中有咱们这个catch这个组件和容器中呢,没有这个catch manager,而且呢,满足这个条件,它呢就会生效等等等等,那我们这有11个配置,我们在这截了图,到底哪个有生效,好我们先把它停一下,我们就不一一分析了,大家可以分析类头,我们呢,在我们这个配置上,我们来加一个debug等你处,那么这样的话呢,来启动的时候就会打开我们这个自动配置报告,好来运行一下,我们就来看一下到底是哪个缓存配置生效。
03:43
有这么多的缓存配置,我们直接在控制台看这个配置报告,我们来搜一下catch configuration control f看configuration能看到有一个叫simple configuration match的,哎,它匹配上了,那其他的configuration呢?哎,往下看。
04:02
哎,这个呢,Canfe这个没匹配上,包括呢,这个coach的没匹匹配上yet catch的,哎,都don't match,所以说呢,我们现在唯一有一个匹配上的叫simple,哎,我们来看一下,就是刚才的这个simple catch configuration。那么我们来默认呢,是它生效的,它呢,生效呢,它做了什么?我们来看一下CTRLN进来,它呢,给容器中放了一个an b,诶,放了一个什么呢?放了一个叫concurrent map catch manager,诶。它的作用呢,就是给容器中。好,我们来记录一下给容器中。给容器中,给容器中。注册了一个catch manager。诶,注册了一个缓存管理器,这个缓存管理器呢,叫concurrent map catch manager,那我们来看一下这个缓存管理器,缓存管理器的作用,哎,你实现了这个catch manager,就有一个方法叫get catch,按照一个名字得到一个缓存总件,那么呢,我们这个concurrent catch manager,它的作用呢,我们来给这也打一个断点。
05:23
它按照缓存的名字来得到一个缓存组件,怎么得到呢?我们来大概分析一它一下所有的缓存的名字跟缓存的对应关系,它存在了这个map中,哎,这个map里边它是一个C,它哈西map,哎,里边是string,是缓存的名字以及缓存这个组件的对象,那么这个catch map呢?来达到这个断点,它会来。获取,按照这个名字获取到这个组件,如果说这个组件获取为空,哎,他呢在这儿锁一下,然后呢,在尝试获取,如果为空会来创建,诶,Create con currentent map catch点进来我们会看到呢,在这会创建一个缓存组件,比如说诶我们这个catch manager的一个作用。
06:14
就是说呢,它可以啊,获取和创建咱们这个这个类型的缓存组件,那么这个类型的缓存组件呢,我们来点进来,我们会看到呢,这里边有一些缓存的方法,比如查一些缓存的数据,Look up或者get。他们呢,就是从这个里边查,我们给这些方法也打上断点,从这个store,而这个store呢,我们来看一下,在上边其实呢,它就是一个map,哎concurrent map,比如说呢,哎。它的作用。是将咱们这个数据保存在在我们这个concurrent map里边,好,我们给它刚才打的断点,我们点进来这个store,点进来保存在这儿。
07:06
诶,从这个中呢,我们来存取数据,这是我们我们现在呢,看到自动配置来默认呢,容器中相当于使用con map catch manager和concuent map catch这个组件来进行。那缓存的运行的步骤是什么呢?这个运行的流程是什么?那么我们给我们这个目标方法,我们来打上断点,包括呢,我们缓存的这些操作,来从缓存里边这个con map catch,它如何获取数据的来打上断点,包括呢,它保存数据的时候,哎,这有一个put也打上断点,你就分别来看一下这些方法它们的调用时机。我们呢就把它停掉,我们以debug的模式进行运行,好我们启动起来,诶这一块提示呢,说我们给方法上打上断电,可能会导致我们这个debug变慢啊,我们把这个停掉啊,我们这个断点呢,我们不打在方法上,我们打在这个行内,每一个呢,我们都这样打employee service,这样也是一样好,我们打在行内,包括这个catch manager catch manager呢,它也会来获取缓存,这个我们也打在这个行内,好。
08:17
获取到coner map这个看的这个缓存,把这一块的断点也打在行内,好我们都换过来,然后呢,我们来以debug模式启动。好,现在呢,没有这个提示,好我们来看一下这几个方法的调用顺序。首先呢,我们来获取咱们这个二号,二号员工来发一个请求,我来刷新,那么方法呢,首先来到第一步,我们会发现在我们没掉我们这个方法之前,诶,我们这个方法的断点还没进来之前,我们先来到第一步叫get catch,先获取缓存,获取哪个缓存呢?获取emp,而这个E呢,就是我们这一块指定的这个names做运行流程第一步。
09:04
方法运行之前。当我们是以这个catch able不来作为例子的方法运行之前,先去查询咱们这个catch,也就说查询我们这个缓存组件,然后呢,按照咱们这个catch names指定的名字获取。它是怎么获取呢?我们也看到了,是先来调用catch manager里边的get catch方法获取的呢,这一步我我们总结起来就是catch manage先获取。相应的缓存。这是我们第一步,然后呢,第二步我们来看拿这个缓存,它怎么拿这个缓存呢,我们来往下走,由于我们这个缓存呢,我们来看啊,第一次拿到的这个看尺是闹,哎,我们从来没有创建过名叫emp的某一个缓存对象等等等等,所以呢,第一次获取缓存我们会发现它没有,没有的话呢,下边会调一个create concurrent map,我创建一个缓存,会创建帮我们创建出叫concuent map catch,这里边呢有一个store叫conent has map来保存数据的,所以呢,我们来说第一次。
10:30
第一次获取缓存会咱们这个会自动创建出来创建,那如果没有。如果没有看主线。会先自动创建出来,那么自动创建出来以后呢,那我们以后就能用了,它把创建出来的缓存组件都放在这个catch map里边,好,那么我们继续来放行,这是第一步,先得到我们这个catch缓存组件来,我们来放行,放行以后呢,我们发现它第二步要lookup lookup呢就是查找在这个store里边,这个store里边呢,来查找这个缓存的这个数据。
11:15
要按照某一个KK是几呢?K写了一个二,所以说呢,接下来第二步。去咱们这个catch中查找。咱们这个缓存,诶,因为我们看到它调用的是this,是这个concuron map catch,也就是我们这个catch的实现类,它从这呢去查找缓存的内容,按使用。使用一个K,使用哪个K呢?我们说了这个默认,默认就是方法的参数,诶我们也看到呢,这个K在这一块呢,它传入了一个二,但这个二是怎么得到的,我们可以看它的以前的这个步骤,哎来看它以前步骤看是get k,按照一个k get怎么get呢?这还是do get来上一步,上一步呢,我们来看到这有一个China right k叫生成一个K,然后呢,这个K呢,它是生成出来的。
12:13
来在这儿呢,再来记录一下。K。是按照。某种某种策略生成的。哪种策略呢?我们在这大致的来看一下generated k,我点进来,哎,它呢,调用上下文generated k来生成这个K生成的时候呢,诶大家来看啊,它调用了一个东西叫什么呢?K generate generated,把我们这个target对象以及方法与参数都传了进来,所以呢,来给大家来说一下这个关键步骤,那么这个默认是使用。是使用。
13:01
使用咱们这个key generator生成的,而这个key generator。我们来看一下这个key generator呀。好,我们来它的这个上一步点进来这个key generator,来我们看这个key generator呢,它的值它叫simple key generator,默认是用这个名叫simple key genator的东西,好把这个key genator点进来,这是一个接口CTRLH,它的这个实现有一个呢叫simple key genator,把这个呢复制过来。就是它好,我们来还是记录在这儿。默认使用simple k generator生成K,这个simple k genator怎么生成呢?那我们下一步再看吧,我们现在呢,知道他会帮我们来先来生成K,先来查缓存有没有,那么这是方法第一次运行肯定没有,我们来让他查询来返回它查到的这个VALUE6呢,我们看到这是空的,没有的情况下怎么办呢?我来放行,没有的情况下呢,哎,它就应该调用目标方法了,但是他在这呢,先来put put一个这个值,这个值就是已经是目标方法返回的了,能给目标方法。
14:16
没有打上断点吗?来看一下这个目标方法,哎,查询二号员工已经调用了,哎,只不过我把这个断点给放行了,所以呢。如果说没有。看到这儿接下来呢,没有查到缓存。就调用目标方法。目标啊,调用目标方法,然后呢,调用完了以后,第四步我们看到目标方法被调用SQL语句发了,然后呢,将目标方法返回的结果。啊,放进缓存里边。哎,我们这个方法呢,咱们在这debug,诶它是调用这个put方法,诶由于我们用的是concuent map,这个看这个store里边呢,它是用con map来做我们这个缓存数据的,所以呢,它会把这个信息AK,就是我们这个二号数据,然后呢,哎,值值呢,就是我们方法的返回值M这个二号李四它来放进我们这个道里边了啊运行。
15:19
好,至此呢,我们整个流程就运行完了,有说方法,执行之前先检查缓存一句话。方法执行之前。Catch标注的方法。看吃Apple。标注的方法。执行之前先来检查缓存。检查缓存中有没有这个数据,按照默认,默认按照咱们这个参数的值作为K。去查询缓存,那如果没有。
16:01
如果没有,那么就我们就应该运行方法,如果没有就运行方法,并将。并将结果放入缓存。这是我们看到第一步啊,如这是我们第一次运行出来,它放进缓存了,那如果我第二次运行呢,我再来刷新一遍,刷新我们来到这个debug,还是拿到我们这个缓存组件好,我直接来放行,然后呢,我们要从缓存中去查,查的第一步是要生成我们这个KK是怎么生成的,我们现在可以进来看一下,我来step into来用咱们这个上下文调用我们来生成这个K,生成K呢,我们来主要看下边它是调这个k generator,这个k generator呢,就叫simple k generator它怎么生成呢?Into进来。他呢,将我们这个参数传了进来,参数的所有的这个数组,我们现在就一个参数传进来,斯大夫音图我们会看到,如果说没有参数,就直接返回一个simple key empty,相当于一个simple key对象,哎,把它作为K,如果说有一个参数,就把这个参数拿来直接返回,如果有多个参数,把多个算数都帮装返回这个simple k对象,所以这是它默认的K的生成策略,来也记录一下。
17:25
生成策略。他的sy generator。生成T的策略。K的默认策略,如果没有参数,那么K就使用的它是一个默认的,叫他自己用了一个simple key。这个对象。它呢,K就是用它做的,如果有一个参数,那么就是K就是就等于咱们这个参数的值,而如果有多个参数,它呢,这个K就是。
18:10
就是我们刚才看到的这个simple key包装了我们这个多个参数的这个对象,它是用它。来PAR。Harms好,它是用他们来作为K的,我们在这儿呢,顺便也看到了咱们缓存的,哎,咱们这个K的生成策略,好,那么回到我们这个结果,那么这个K呢,生成了以后啊,我们来直接放行。我们把这个K呢,我们让它生成我们只有一个参数,所以呢,返回这个参数二的值,好生成K。好,生成K以后呢,接下来found in catch,我们就在缓存中按照这个K来找来放行,由于之前我们已经运行过一次这个store里边呢,我们看到有了这个二号对应的这个员工数据,所以呢,直接从咱们这个缓存中拿到这个数据,拿到这个数据以后呢,将们这个数据哎,直接就返回了,返回了以后呢,诶,我们已经拿到这个数据了,那我们就不用调用方法了,数据不等于空,那直接啊我们返回,如果说数据为空了,我们才调方法好那。
19:21
直接放行,我们发现没有调用方法,所以呢,这就是我们第二次调用以后呢再来调用。以后再来调用就可以直接。使用缓存中的数据,那么这就是我们整个缓存的运行原理,在这个原理里边核心的两个我们需要关注的点,它的核心核心呢?第一个核心就是我们使用catch manager,按照名字得到catch组件,使用我们这个catch manager。
20:01
按照名字得到catch组件。而这个catch manager呢,没配置的情况下,默认就是这个叫concurrent map catch manager,当然他得到的缓存组件就是concuent map这个catch组件,这个组件呢给啊是用一个concu has map来当做啊,咱们这个数缓存的这个保存数据的中心,好这是第一个,第二个也就说呢,我们K是使用咱们这个叫key generator生成的。是使用key generator生成的。那么默认的generate呢?默认是咱们这个symbol k generate来帮我们生成这个,然后呢,接下来就是我们缓存的运行步骤,先来检查缓存,如果缓存中有就用缓存的,如果没有再来调方法,这就是我们缓存的整个运行流程。
我来说两句