百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

springboot-如何集成Redis启用缓存功能

mhr18 2024-11-06 11:02 25 浏览 0 评论

一、步骤概览

二、步骤说明

1.引入依赖

在 pom.xml 文件引入 spring-boot-starter-data-redis、commons-pool2、jackson-databind 依赖包。依赖详情如图所示:

  • spring-boot-starter-cache:缓存功能集成包。
    • spring-boot-starter-data-redis:Redis 集成包。
    • commons-pool2:Redis 连接池用到的依赖包。
    • jackson-databind:Redis 序列化和反序列需要用到的依赖包。

    2.定义连接参数

    在 aplication.yml 文件中定义 redis 相关连接参数,连接示例如下所示:

    spring:
      redis:
        # Redis所在库索引
        database: 1
        # Redis 主机地址
        host: 127.0.0.1
        # Redis 连接端口
        port: 6379
        # Redis 访问密码
        password:
        # Redis 连接超时时间
        timeout: 5000
        # Redis 连接池设置
        lettuce:
          pool:
            # 最大连接数
            max-active: 8
            # 最大等待时间,单位毫秒
            max-wait: 5000

    3.定义配置类

    定义Redis配置类 RedisConfig(需要添加@Configuration注解),进行Redis的相关配置,主要包括

    ①. 配置RedisTemplate模板

    由于默认情况下,RedisTemplate 使用了 JdkSerializationRedisSerializer 进行键和值的序列化,但是这种方式可能会存在一些问题(如序列化效率低)或者无法满足业务需求(如需要将数据序列化为 JSON 格式),因此需要重新配置 SerializationRedisSerializer 或 Jackson2JsonRedisSerializer 等其他序列化方式,配置代码如下所示:

    • com.shawn.springboot.integeration.redis.config.redis.RedisConfig#redisTemplate
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
      RedisTemplate<String, Object> template = new RedisTemplate<>();
      template.setConnectionFactory(factory);
      Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
      ObjectMapper om = new ObjectMapper();
      // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常
      om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                               ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
      jacksonSeial.setObjectMapper(om);
      // 值采用json序列化
      template.setValueSerializer(jacksonSeial);
      //使用StringRedisSerializer来序列化和反序列化redis的key值
      template.setKeySerializer(new StringRedisSerializer());
      // 设置hash key 和value序列化模式
      template.setHashKeySerializer(new StringRedisSerializer());
      template.setHashValueSerializer(jacksonSeial);
      template.afterPropertiesSet();
      return template;
    }

    ②. 配置缓存管理器

    通过配置缓存管理器,可以将 Redis 作为缓存存储介质,并利用缓存管理器来统一管理缓存的创建、读取、更新和删除操作,从而提高系统性能和响应速度。

    如果不配置缓存管理器,那么在业务代码中就需要手动调用 RedisTemplate 的一些方法来完成缓存的相关操作,而无法使用相关的缓存注解如 @Cacheable、@CachePut、@CacheEvict等方法,配置代码如下所示:

    • com.shawn.springboot.integeration.redis.config.redis.RedisConfig#cacheManager
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
      // 生成两套默认配置,通过 Config 对象即可对缓存进行自定义配置
      RedisCacheConfiguration cacheConfig1 = RedisCacheConfiguration.defaultCacheConfig()
      // 设置过期时间 10 分钟
        .entryTtl(Duration.ofMinutes(10))
        .prefixCacheNameWith("cache:user:")
      // 禁止缓存 null 值
        .disableCachingNullValues()
      // 设置 key 序列化
        .serializeKeysWith(keyPair())
      // 设置 value 序列化
        .serializeValuesWith(valuePair());
    
      RedisCacheConfiguration cacheConfig2 = RedisCacheConfiguration.defaultCacheConfig()
      // 设置过期时间 30 秒
        .entryTtl(Duration.ofSeconds(30))
        .prefixCacheNameWith("cache:admin:")
        .disableCachingNullValues()
        .serializeKeysWith(keyPair())
        .serializeValuesWith(valuePair());
    
      // 返回 Redis 缓存管理器
      return RedisCacheManager.builder(factory)
        .withCacheConfiguration("user", cacheConfig1)
        .withCacheConfiguration("admin", cacheConfig2)
        .build();
    }
    • com.shawn.springboot.integeration.redis.config.redis.RedisConfig#keyPair
    // 用于缓存管理器 key 序列化
    private RedisSerializationContext.SerializationPair<String> keyPair() {
      	return RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());
    }
    • com.shawn.springboot.integeration.redis.config.redis.RedisConfig#valuePair
    // 用户缓存管理器value序列化
    private RedisSerializationContext.SerializationPair<Object> valuePair() {
       //使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis的 value值(默认使用JDK的序列化方式)
       Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
    
       ObjectMapper om = new ObjectMapper();
       // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
       om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
       // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
       om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                               ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
       jacksonSeial.setObjectMapper(om);
      return RedisSerializationContext.SerializationPair.fromSerializer(jacksonSeial);
    }

    4.启用缓存

    在 springboot 启动类上添加 @EnableCaching 注解启用缓存功能,当在启动类上添加 @EnableCaching 注解时,Spring Boot 会自动检测项目中的缓存依赖(如 Spring Data Redis、Ehcache 等)并进行相应的配置。这样,你就可以在类中使用 Spring 的缓存注解(如 @Cacheable、@CachePut、@CacheEvict 等)来实现缓存功能。

    三、如何使用缓存注解

    1. @Cacheable

    @Cacheable 注解可以标记在方法上,表示该方法的返回结果将会被缓存起来,以便后续直接从缓存中获取数据。示例代码:

    @Cacheable(value = {"product"}, key = "#id")
    @Override
    public Product select(String id) {
      // 模拟从数据库中获取数据
      Product product = stringProductHashMap.get(id);
      log.info("从 DB 中查询产品:[{}]", id);
      return product;
    }
    • value: 表示缓存的名称,即指定将结果缓存在哪个缓存区域中。在示例中,value = {"product"} 表示将结果缓存在名为 "product" 的缓存区域中。
    • key: 用于指定缓存的键值,即根据 key 来存储和获取缓存中的数据。在示例中,key = "#id" 表示根据方法的参数 id 来作为缓存的键值。

    2. @CachePut

    @CachePut 注解表示被注解的方法总是会执行,并且将方法返回的结果放入缓存中。示例代码:

    @CachePut(value = "product", key = "#product.id")
    @Override
    public Product saveOrUpdate(Product product) {
      // 模拟数据库保存数据
      stringProductHashMap.put(product.getId().toString(), product);
      log.info("从 DB 中更新产品:[{}]", product.getId());
      return product;
    }

    这里的 key = "#product.id" 表示缓存的键值是根据方法参数 product 对象的 id 属性来确定的。

    当 saveOrUpdate 方法执行时,如果缓存中已存在相同 id 的记录,则会使用新的 product 对象更新缓存中的数据。由于缓存的键值是根据 product 的 id 属性来确定的,因此每次更新缓存时都会根据最新的 product 对象重新生成缓存的键值。

    3. @CacheEvict

    @CacheEvict 注解表示被注解的方法执行后将清除指定的缓存项。示例代码:

    @CacheEvict(value = "product", key = "#id")
    @Override
    public void delete(String id) {
      // 模拟数据库操作
      stringProductHashMap.remove(id);
      log.info("从 DB 中删除产品:[{}]", id);
    }

    相关推荐

    如何检查 Linux 服务器是物理服务器还是虚拟服务器?

    在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...

    第四节 Windows 系统 Docker 安装全指南

    一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...

    C++ std:shared_ptr自定义allocator引入内存池

    当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...

    Activiti 8.0.0 发布,业务流程管理与工作流系统

    Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...

    MyBatis动态SQL的5种高级玩法,90%的人只用过3种

    MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...

    Springboot数据访问(整合Mybatis Plus)

    Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...

    盘点金州勇士在奥克兰13年的13大球星 满满的全是...

    见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...

    Mybatis入门看这一篇就够了(mybatis快速入门)

    什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...

    Springboot数据访问(整合druid数据源)

    Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...

    Linux 中的 &quot;/etc/profile.d&quot; 目录有什么作用 ?

    什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...

    企业数据库安全管理规范(企业数据库安全管理规范最新版)

    1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...

    Oracle 伪列!这些隐藏用法你都知道吗?

    在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...

    Oracle 高效处理数据的隐藏神器:临时表妙用

    各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...

    Oracle 数据库查询:多表查询(oracle多表关联查询)

    一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...

    一文掌握怎么利用Shell+Python实现多数据源的异地备份程序

    简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...

    取消回复欢迎 发表评论: