Springboot如何集成spring cache缓存
这篇“Springboot如何集成spring cache缓存”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Springboot如何集成spring cache缓存”文章吧。
一、为什么要做缓存
提升性能
绝大多数情况下,关系型数据库select查询是出现性能问题最大的地方。一方面,select 会有很多像 join、group、order、like 等这样丰富的语义,而这些语义是非常耗性能的;另一方面,大多数应用都是读多写少,所以加剧了慢查询的问题。
分布式系统中远程调用也会耗很多性能,因为有网络开销,会导致整体的响应时间下降。为了挽救这样的性能开销,在业务允许的情况(不需要太实时的数据)下,使用缓存是非常必要的事情。
缓解数据库压力
当用户请求增多时,数据库的压力将大大增加,通过缓存能够大大降低数据库的压力。
二、常用缓存操作流程
使用缓存最关键的一点就是保证:缓存与数据库的数据一致性,该怎么去做?下图是一种最常用的缓存操作模式,来保证数据一致性。
更新写数据:先把数据存到数据库中,然后再让缓存失效或更新。缓存操作失败,数据库事务回滚。
删除写数据: 先从数据库里面删掉数据,再从缓存里面删掉。缓存操作失败,数据库事务回滚。
查询读数据
缓存命中:先去缓存 cache 中取数据,取到后返回结果。
缓存失效:应用程序先从 cache 取数据,没有得到,则从数据库中取数据,成功后,在将数据放到缓存中。
如果上面的这些更新、删除、查询操作流程全都由程序员通过编码来完成的话
因为加入缓存层,程序员的编码量大大增多
缓存层代码和业务代码耦合,造成难以维护的问题。
三、整合Spring Cache
我们可以使用Spring cache解决上面遇到的两个问题,Spring cache通过注解的方式来操作缓存,一定程度上减少了程序员缓存操作代码编写量。注解添加和移除都很方便,不与业务代码耦合,容易维护。
第一步:pom.xml 添加 Spring Boot 的 jar 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId></dependency>
添加入口启动类 @EnableCaching 注解开启 Caching,实例如下。
@EnableCaching
在Spring Boot中通过@EnableCaching
注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者,也就是说Spring Cache支持下面的这些缓存框架:
Generic
JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
EhCache 2.x
Hazelcast
Infinispan
Couchbase
Redis(因为我们之前引入了Redis,所以使用redis作为缓存)
Caffeine
Simple
四、在ArticleController类上实现一个简单的例子
下面的例子第一次访问走数据库(代码上断点断下来),第二次访问就走缓存了(不走函数代码)。可以自己下断点试一下。
@Cacheable(value="article")@GetMapping( "/article/{id}")public @ResponseBody AjaxResponse getArticle(@PathVariable Long id) {
使用redis缓存,被缓存的对象(函数返回值)有几个非常需要注意的点:
必须实现无参的构造函数
需要实现Serializable 接口和定义serialVersionUID (因为缓存需要使用JDK的方式序列化和反序列化)。
本专栏后续文章中会给出更加详细的例子说明。
五、更改Redis缓存的序列化方式
让缓存使用JDK默认的序列化和反序列化方式非常不友好,我们完全可以修改为使用JSON序列化与反序列化的方式,可读性更强,体积更小,速度更快。
@Configurationpublic class RedisConfig { //这个函数是上一节的内容 @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); //重点在这四行代码 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } //本节的重点配置,让Redis缓存的序列化方式使用redisTemplate.getValueSerializer() //不在使用JDK默认的序列化方式 @Bean public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) { RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory()); RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())); return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); }}
以上就是关于“Springboot如何集成spring cache缓存”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341