暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot快速集成Redis

起岸星辰 2021-06-21
469

Redis一个基于内存实现的NoSql数据库,通常将其用于数据缓存以此来减少系统的压力,下面我将在SpringBoot中实现Redis各个模式在项目中的使用。


Redis的相关安装教程这里不再赘述,请参考Docker上安装Redis。示例项目源代码https://github.com/vcharfred/spring-demo的Hoxton分支的redis-template*模块中 。

添加redis的自动装配类

版本号不用写,直接使用springboot默认适配的版本即可

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- 使用lettuce做redis的连接池需要额外引入这个包-->
    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    </dependency>
    复制

    开箱即用的配置

    正如标题所说开箱即用,我们只需要在application.yml配置类里面添加如下redis配置即可

      spring:
      redis:
      # 地址
      host: 192.168.56.102
      # 端口号
      port: 3306
      # 密码
      password: 123456
      # 超时时间,单位毫秒
      timeout: 3000
      # 数据库编号
      database: 0
      # 配置lettuce
      lettuce:
      pool:
      # 连接池中的最小空闲连接
      min-idle: 1
      # 连接池中的最大空闲连接
      max-idle: 6
      # 连接池最大连接数(使用负值表示没有限制,不要配置过大,否则可能会影响redis的性能)
      max-active: 10
      # 连接池最大阻塞等待时间(使用负值表示没有限制);单位毫秒
      max-wait: 1000
      #关闭超时时间;单位毫秒
      shutdown-timeout: 200
      复制

      springboot的redis自动装配类已经配置了一个StringRedisTemplate的bean,如果操作都是使用String的数据类型,那么直接使用即可,使用示例

        @Autowired
        private StringRedisTemplate stringRedisTemplate;


        /**
        * 增删查改示例1
        */
        @Override
        public String crud1() {
        ValueOperations<String, String> operations = this.stringRedisTemplate.opsForValue();
        // 获取数据
        String val = operations.get("student:1");
        if(null==val){
        log.info("缓存中数据不存在");
        Student student = Student.create();
        val = JSON.toJSONString(student);
        // 添加数据
        operations.set("student:1", val);


        Student student2 = Student.create();
        student2.setId(2L);
        operations.set("student:2", JSON.toJSONString(student2));
        this.stringRedisTemplate.opsForList().leftPush("student_list", JSON.toJSONString(student));
        this.stringRedisTemplate.opsForList().leftPush("student_list", JSON.toJSONString(student2));


        }else {
        // 删除数据
        this.stringRedisTemplate.delete("student:2");
        log.info("删除缓存");
        }
        log.info(val);


        // 获取列表数据
        List<String> list = this.stringRedisTemplate.opsForList().range("student_list", 0, 3);
        log.info(JSON.toJSONString(list));
        return val;
        }
        复制

        自定义配置Redis操作的bean

        StringRedisTemplate虽然可以满足需求,但是还是需要我们去序列化一下;因此我简化操作我们需要自定义配置创建RedisTemplate的bean。
        创建一个配置类继承CachingConfigurerSupport类。

          @Configuration
          public class RedisConfig<K, V> extends CachingConfigurerSupport {


          /**
          * 自定义缓存注解key的生成策略。默认的生成策略是看不懂的(乱码内容)
          * 通过Spring 的依赖注入特性进行自定义的配置注入并且此类是一个配置类可以更多程度的自定义配置
          * 这里是生成的key是:类全名.方法名 方法参数(的md5加密)
          */
          @Bean
          @Override
          public KeyGenerator keyGenerator() {
          return (target, method, params) -> {
          StringBuilder prefix = new StringBuilder();
          prefix.append(target.getClass().getName());
          prefix.append(".").append(method.getName());
          StringBuilder sb = new StringBuilder();
          for (Object obj : params) {
          sb.append(obj.toString());
          }
          return prefix.append(DigestUtils.md5DigestAsHex(sb.toString().getBytes()));
          };
          }


          /**
          * 缓存配置管理器
          */
          @Bean
          public CacheManager cacheManager(LettuceConnectionFactory factory) {
          //以锁写入的方式创建RedisCacheWriter对象
          RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
          //设置缓存注解的缓存时间,缓存1小时
          Duration duration = Duration.ofSeconds(3600L);
          RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(duration);
          return new RedisCacheManager(writer, redisCacheConfiguration);
          }


          /**
          * 修改redisTemplate的序列化方式
          *
          * @param factory LettuceConnectionFactory
          */
          @Bean(name = "redisTemplate")
          public RedisTemplate<K, V> redisTemplate(LettuceConnectionFactory factory) {
          //创建RedisTemplate对象
          RedisTemplate<K, V> template = new RedisTemplate<K, V>();
          template.setConnectionFactory(factory);
          //设置key的序列化方式
          template.setKeySerializer(keySerializer());
          template.setHashKeySerializer(keySerializer());


          //设置RedisTemplate的Value序列化方式Jackson2JsonRedisSerializer;默认是JdkSerializationRedisSerializer
          template.setValueSerializer(valueSerializer());
          template.setHashValueSerializer(valueSerializer());


          template.afterPropertiesSet();
          return template;
          }


          private RedisSerializer<String> keySerializer() {
          return new StringRedisSerializer();
          }


          private RedisSerializer<Object> valueSerializer() {
          Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(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);
          //解决时间序列化问题
          om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
          om.registerModule(new JavaTimeModule());


          jackson2JsonRedisSerializer.setObjectMapper(om);
          return jackson2JsonRedisSerializer;
          }


          }
          复制

          使用示例

            @Autowired
            private RedisTemplate<String, Student> redisTemplate;


            @Override
            public Student crud2() {
            ValueOperations<String, Student> operations = this.redisTemplate.opsForValue();
            // 获取数据
            Student val = operations.get("student2:1");
            if(null==val){
            log.info("缓存中数据不存在");
            val = Student.create();
            // 添加数据
            operations.set("student2:1", val);

            Student student2 = Student.create();
            student2.setId(2L);
            operations.set("student2:2", student2);
            this.redisTemplate.opsForList().leftPush("student_list2", val);
            this.redisTemplate.opsForList().leftPush("student_list2", student2);
            }else {
            // 删除数据
            this.redisTemplate.delete("student2:2");
            log.info("删除缓存");
            }
            log.info(JSON.toJSONString(val));

            // 获取列表数据
            List<Student> list = this.redisTemplate.opsForList().range("student_list2", 0, 3);
            log.info(JSON.toJSONString(list));
            return val;
            }
            复制


            文章转载自起岸星辰,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论