• SpringBoot Redis 实践指南


    前言

    SpringBoot Cache 是一个很好的缓存框架,可以兼容多种缓存实现,数据量较大的情况下,Redis 应该是最多被使用的。

    本文重点介绍 SpringBoot 和 Redis 整合使用的关键流程,并对其中的核心要点给出说明,且附上相应的官方文档链接便于参考。

    添加 Maven 依赖

    在项目 pom.xml 中添加如下配置:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
    

    启用缓存

    在项目 启动类 中添加如下注解:

    @EnableCaching
    

    配置缓存

    配置 Redis 连接信息

    Redis 连接信息包括地址、端口、超时时间(秒)和连接池等,可以根据需要选取若干配置即可。

    在项目 application.yml 中添加如下配置:

    spring:
      redis:
        host: ${host}
        port: ${port}
        timeout: 3000
        lettuce:
          pool:
            enabled: true
            max-active: 30
    

    SpringBoot 默认使用的 Redis 客户端是 lettuce,不是 Jedis。如果需要使用连接池的话,还需要额外添加一个 Maven 依赖:

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>${commons-pool2.version}</version>
    </dependency>
    

    Redis 连接配置属性参考,注意属性前缀为 spring.redis.*。

    配置缓存信息

    SpringBoot 支持多个不同名称的缓存,缓存名称需要预先配置,还可以指定缓存的过期时间。对于 Redis 而言,某个名称的缓存实际上就是 Redis 中一个或多个以该名称为前缀的 Key,缓存的过期时间指的就是这部分 Key 的过期时间。

    在项目 application.yml 中添加如下配置:

    spring:
      cache:
        cache-names: "cache1,cache2"
        redis:
          time-to-live: "10m"
    

    缓存配置属性参考,注意属性前缀为 spring.cache.redis.*。

    默认情况下,所有缓存的过期时间都是一样的。如果需要对不同的缓存设置不同的过期时间,可以自己扩展实现,参考官方示例

    使用缓存

    @Cacheable

    SpringBoot Cache 可以帮助我们自动缓存某个方法的结果(返回值),使用时我们只需要在方法上面添加注解 @Cacheable,并且指定缓存名称即可:

    @Cacheable(cacheNames = {"cos::url"})
    public String generatePresignedUrl(String name) {
      return ...;
    }
    

    缓存名称为 cos::url,调用方法 generatePresignedUrl 时,SpringBoot Cache 会自动检查 Redis 中是否已经缓存过该方法的结果,如果已经缓存过,则直接使用缓存中的结果返回,该方法不会执行;如果没有缓存过,会执行该方法获取结果,缓存结果之后再返回给调用者。

    Caching

    Key Generation

    Redis 检查或缓存结果时均需要一个 Key,SpringBoot Cache 使用 缓存名称(CacheName,如:cos::url)和 参数值(ParameterValue,如:value1)生成 Key,规则如下:

    • 如果方法没有参数,Key 为 CacheName::SimpleKey [],即:cos::url::SimpleKey [];
    • 如果方法只有一个参数,Key 为 CacheName::ParameterValue,即:cos::url::value1;
    • 如果方法有两个或两个以上的参数,Key 为 CacheName::SimpleKey [ParameterValue1,ParameterValue2,...],即:cos::url::SimpleKey [value1,value2];

    Default Key Generation

    sync

    sync 是注解 @Cacheable 的一个属性,值可以是 true 或 false:

    如果 sync = false(默认),多线程环境下调用方法 generatePresignedUrl 时,Redis 没有缓存结果的情况下,方法可能会被执行多次;
    如果 sync = true,Redis 没有缓存结果的情况下,方法 generatePresignedUrl 只会被执行一次。

    Conditional Caching

    condition

    condition 是注解 @Cacheable 的一个属性,它的值是一个 SpEL 表达式,表达式的计算结果可以是 true 或 false:

    如果表达式的计算结果是 true,表示缓存方法结果;
    如果表达式的计算结果是 false,表示不缓存方法结果;

    Conditional Caching

    SpEL 表达式可以使用方法的参数值,也可以调用该方法所在 Bean 的其它方法,如:

    #name.length() < 32
    

    方法参数 name 的参数值长度小于 32 时,方法结果才会被缓存;

    condition = "#root.target.check(#name)"
    

    check() 必须是公开的(public),且返回值必须是布尔类型(Boolean);只有 check() 返回值为 true 时,方法结果才会被缓存。

    Available Caching SpEL Evaluation Context

    使用限制

    如果方法 generatePresignedUrl 被位于一个 Bean 的其它方法调用时,缓存不会生效;也就是说,方法 generatePresignedUrl 必须被其它 Bean 的方法调用时,缓存才会生效。原因主要是和 Spring 的代理机制有关,详情可以参考:Spring Cache @Cacheable - not working while calling from another method of the same bean

    SpringBoot Cache 还支持其它注解,可以参考 Declarative Annotation-based Caching

    RedisTemplate

    如果我们需要自己实现缓存逻辑,SpringBoot Cache 提供了一个封装 Redis 常用操作的工具模板类:RedisTemplate,并且会创建好它的实例,使用时直接注入即可:

    @Autowired
    private StringRedisTemplate template;
    
    @Autowired
    private RedisTemplate<String, String> template2;
    
    @Autowired
    private RedisTemplate<String, Integer> template3;
    

    RedisTemplate 支持泛型,我们可以根据自己的需求注入一个或多个实例;如果键值的类型都是 String,可以直接使用 StringRedisTemplate

    结语

    SpringBoot 整合 Redis 使用时,如果仅仅是需要读取或缓存数据,直接使用注解的方式相较于使用 RedisTemplate 的方式,可以避免大量的缓存冗余代码,更多地关注业务逻辑;但是缺点也比较明显,操控性比较差。实际使用时,可以灵活结合两者,优先使用注解方式;注解方式受限时,再结合 RedisTemplate 作为补充。

  • 相关阅读:
    去除六价铬树脂A-21性能测试
    全球化浪潮下的数据库革新:嘉里物流 TiDB 实践价值的设想
    springcloud:1.Eureka详细讲解
    解决prometheus node cert exporter 的日志输出问题。
    十、http客户端Feign
    [Mamba_4]LMa-UNet
    什么软件可以识别图片上的文字?分享三个实用的识别软件
    无人驾驶与人工驾驶的对比,人工驾驶的优缺点
    Android AMS——栈管理基础(九)
    我如何学习Typescript
  • 原文地址:https://www.cnblogs.com/yurunmiao/p/16281672.html