Springboot 集成spring cache缓存的解决方案

 更新时间:2022年06月02日 08:59:18   作者:字母哥哥  
这篇文章主要介绍了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序列化与反序列化的方式,可读性更强,体积更小,速度更快。

@Configuration
public 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缓存的文章就介绍到这了,更多相关Springboot 集成spring cache缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot Security从入门到实战示例教程

    SpringBoot Security从入门到实战示例教程

    Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架,接下来通过本文给大家介绍SpringBoot Security从入门到实战示例教程,感兴趣的朋友一起看看吧
    2022-05-05
  • 使用SpringBoot代码详细解释<List>的用法

    使用SpringBoot代码详细解释<List>的用法

    List是Java集合框架中的一种数据结构,用于存储一组有序的元素,使用List可以方便地向其中添加、删除或者修改元素,也可以通过下标或者迭代器遍历其中的元素,这篇文章主要介绍了用SpringBoot代码详细解释<List>的用法,需要的朋友可以参考下
    2023-09-09
  • SpringBoot中@Autowired与@Resource的区别小结

    SpringBoot中@Autowired与@Resource的区别小结

    本文主要介绍了SpringBoot中@Autowired与@Resource的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • 将Mybatis升级为Mybatis-Plus的详细过程

    将Mybatis升级为Mybatis-Plus的详细过程

    本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现系统功能无损升级,同时享受MyBatis-Plus带来的便捷特性,如代码简化和性能优化,需要的朋友可以参考下
    2025-04-04
  • 用Java产生100个1-150间不重复数字

    用Java产生100个1-150间不重复数字

    这篇文章主要介绍了用Java产生100个1-150间不重复数字,需要的朋友可以参考下
    2017-02-02
  • springboot启动不了也不报错的问题及解决

    springboot启动不了也不报错的问题及解决

    这篇文章主要介绍了springboot启动不了也不报错的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Java微信公众平台开发(1) 接入微信公众平台

    Java微信公众平台开发(1) 接入微信公众平台

    这篇文章主要为大家详细介绍了Java微信公众平台开发第一步,接入微信公众平台,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Maven profile实现不同环境的配置管理实践

    Maven profile实现不同环境的配置管理实践

    这篇文章主要介绍了Maven profile实现不同环境的配置管理实践,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 详解MyBatis日志如何做到兼容所有常用的日志框架

    详解MyBatis日志如何做到兼容所有常用的日志框架

    这篇文章主要介绍了详解MyBatis日志如何做到兼容所有常用的日志框架,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 解决maven打包排除类不生效maven-compiler-plugin问题

    解决maven打包排除类不生效maven-compiler-plugin问题

    总结:在Spring Boot项目B中作为项目A的依赖时,排除启动类不生效的原因是被其他类引用或父POM引入,解决方法是跳过test编译或注释掉@SpringBootTest(classes={BApplication.class})
    2024-11-11

最新评论