默认使用的是ConcurrentMapCacheManager的ConcurrentMapCache作为缓存组件。
使用ConcurrentMap的时候,是将数据保存在ConcurrentMap<Object,Object>
当中的。
实际在开发过程中,我们经常使用的,是一些缓存中间件的。
比如我们经常使用的redis,memcache,包括我们使用的ehcache,等等,我们都是使用一些缓存中间件。
我们之前讲解原理的时候,也发现了,springboot是支持很多的缓存配置的:
如下图所示的:
默认开始的配置的是:SimpleCacheConfiguration。
其他的缓存是在什么时候开启呢?
我们可以ctrl+n搜索一下,这些配置类,然后进去看看他们的conditional条件:
这些都是表示,当你导入了相应的包的时候,这些配置才会是生效的哦。
如果有不会redis这个技术的同学,尚硅谷当中有周阳老师发布的redis系列的讲解视频。或者大家可以最快地访问redis的官方网站,来进行学习,redis.cn是redis学习的中文网。
搜索redis镜像
这个是连接国外的仓库,速度是比较慢的。
我们推荐使用docker 中国。
docker pull registry.docker-cn.com/library/redis
docker run -d -p 6379:6379 --name myredis [REPOSITORY] docker ps
为了测试,打开redis的连接工具。
我们引入了redis的starter之后,redisAutoConfiguration就起作用了。
这个RedisAutoConfiguration是给容器当中加入了两个组件:
给容器中加入的组件,一个是叫做RedisTemplate,一个是叫做StringRedisTemplate,两个东西。
这两个东西就是用来操作redis的。
这就跟大家以前用的jdbcTemplate一样,用来操作数据库的东西。
这就是spring用来简化操作redis的两个template,如果在程序当中想要用这两个东西,就自动注入就可以了。
redis操作list:
这些看不懂的玩意,全部都是序列化的结果。
默认的序列化器,就是使用的JdkSerializationRedisSerializer。
默认的序列化器,就是使用的JDK的序列化器。
我们来切换成json的序列化器,就可以了。
在测试类当中,自动注入我们自己配置的redisTemplate。
然后我们再次测试保存对象。
这就说明了,我们的序列化器修改成功了。
这就说明白了,如果我们后面要保存对象的时候,我们经常是要修改序列化器的。
我们之前使用的是ConCurrentMap的缓存管理器的。
这个缓存管理器,帮我们来创建出来缓存组件的。
缓存组件来实际给缓存中,进行CRUD的工作的。
现在我们引入了redis之后,会发生什么样的效果呢?
我们还是在application.properties当中将debug=true,这样就可以将自动配置报告来打开。
这样的时候,我们重新启动我们的程序,在控制台当中,我们去搜索一下。
看看是哪一个自动配置类,是生效的呢?
原来默认开启的是:SimpleCacheConfiguration的。
现在我们引入了redis相关的starters之后,程序默认开启的是RedisCacheConfiguration了。
启动程序,直接进行测试就可以了。
说明第一次查询的时候,是查询数据库了。
第二次查询的时候,控制台是没有任何输出的,说明是查询了缓存了。
缓存默认是只有redis开启的。
那么肯定是在redis当中了。
我们可以查看一下:
这个说明一个问题,在k和v都是object的时候,默认保存对象的时候,利用序列化来保存的。我们是想要让redis自动保存为json的。
我们应该怎么做呢?
我们先来分析一下这些过程当中的原理。
1、我们是引入了redis的starter,所以我们的cachemanager变为了rediscachemanager了,
2、默认创建的rediscachemanager在操作我们的数据的时候,传入了一个redistemplate的东西。
3、这个redistemplate是redisautoconfiguration帮我们创建的。这个redistemplate默认使用的序列化机制是jdkserializationredisserializer
的。这个就是相当于,redis默认给我们防止的redisCacheManager还不太符合我们的要求的。
我们怎么办呢?
我们应该自定义CacheManager的。
这个时候,我们再启动项目,来进行测试,这个时候,我们就可以看到redis当中的结果,是我们想要的了。
韫秋下次面试的时候,就可以问那些想要来软件园的人,说,你知道redis starter保存对象的时候,redisTemplate默认的序列化规则是什么吗?
如果我们在使用redis的过程中,我们想要修改默认的序列化规则,我们应该怎么做呢?
我们可以自定义redisCacheManager,然后自定义redisTemplate,在redisTemplate当中传入json相关的序列化器的哦。
我们在数据库当中的,department表当中,放进去一条数据:
我们写一个对应的department操作的mapper。
我们再写一个对应的service
然后我们看看redis当中,是否是有数据的呢?
我们看了,redis当中dept相关的数据,是有的。
我们第二次来查询dept的时候,就应该走缓存redis了。
但是我们第二次去查询的,时候,出现了下面的错误。
上面报错的意思就是说,不能够去读取json的。
因为是要把部门的json对象,转换成为员工的json对象,这是不可以的。
这个就是因为,我们放置的redisCacheManager是操作员工的。
所以,现在我们看到的这个效果,就是很神奇的哦。
缓存的数据,能够存入到redis当中。
但是我们第二次从缓存中查询的时候,就不能够反序列化回来了。
原来就是,我们存的是dept的json的数据,我们的cachemanager,默认是用employee的template来操作redis的。
这个东西只能够将employee的数据反序列化过来的。
这个时候,就等于有了2个redisCacheManager了,我们用哪个呢?
我们在service当中,是可以指定的。
然后我们重启项目,结果是报错了:
如果,我们是有多个cacheManager的话,我们一定是要把某一个cacheManager作为,我们的默认配置的缓存管理器的。
比如,我们可以进行下面的操作,来修复这个启动报错的内容的呢:
这个时候,看看,我们在进行第二次部门查询的时候,能不能够正常地,成功地,从redis当中反序列化地读取到,我们的部门信息呢?
这个时候,我们就发现,不管是员工还是部门,我们都是可以从redis当中反序列化成功查询的。
这个就是很完美的啦。
前面我们说的,全部都是使用注解的方式,来给缓存当中,来放置数据的。
但是,在开发当中,我们经常会,遇到这样的情况。
就是,我们开发进行到某个阶段,我们是需要将一些数据,放到缓存当中的。
我们是需要,使用编码的方式,来操作缓存的。
比如我们在查询出来了部门的信息之后,就希望把这个信息,放入到redis当中。
我们可以把部门的cacheManager注入进来。
然后我们在编码的过程中,可以通过操作这个cacheManager来获取缓存,
然后,再操作缓存组件,来对数据进行增删改查。
我们对上面的代码,启动项目进行测试,发现是可以的,是成功地给redis当中放进去了数据的:
到这里,韫秋我是发现,根本没有将什么有用的东西嘛。
只是讲解了缓存的注解版和编码版。注解版里面讲了@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheManager等这些。
还有就是redis的整合。其实主要就是,我们要写一个redis的配置类,然后在配置类当中,给IOC容器注入redisCacheManager或者是redisTemplate这些东西。