栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

Springboot整合Redis

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot整合Redis

spring boot 整合 Redis配置
  • 准备工作
  • 整合Redis
  • 解释乱码原因
  • 解决办法

准备工作
  • 如果Redis是在远程或者在linux虚拟机中,需要先关闭防火墙,或者将Redis服务运行的端口打开(任意选择一种方式即可)

    • 方法1. 关闭防火墙 (CentOS中)

      #直接关闭防火墙
      [root@localhost bin]# systemctl stop firewalld
      
    • 方法2. 打开Redis服务端口,假如我Redis的端口是6379

      [root@localhost redisconf]# firewall-cmd --zone=public --add-port=6379/tcp --permanent
      success
      
      #重新加载
      [root@localhost redisconf]# firewall-cmd --reload
      success
      #查看所有开放的端口
      [root@localhost redisconf]# firewall-cmd --permanent --zone=public --list-ports
      6379/tcp
      
      #读取配置文件启动Redis服务
      [root@localhost bin]# /redis-server redisconf/redis.conf
      
  • 需要关闭Redis的保护模式,如果开启了该模式,则只有本机能连接该Redis,其他外部的IP是无法连接的,在redis.conf中修改

  • 如果Redis是在远程或者在linux虚拟机中,需要先启动Redis服务,也就是执行redis-server redis.conf

整合Redis

步骤:

  1. 添加Redis依赖

springboot已经将对Redis的操作已经封装成一个类了,我们需要在springboot引入一个Redis依赖,该依赖中底层连接Redis的方法现在不是使用的 Jedis,而是使用的lettuce,因为lettuce是线程安全的,而Jedis是线程不安全的



  org.springframework.boot
  spring-boot-starter-data-redis


在添加完这个依赖之后,spring Boot就会帮我们创建两个对象并放到了Spring容器中,叫做:RedisTemplate 和 StringRedisTemplate ,这两个对象就是我们在springboot中操作Redis需要使用的。

注意:RedisTemplate对象可以用来操作Redis中任意数据类型,比如String,List,Set,Zset,Hash等,而StringRedisTemplate只能操作String类型

  1. 在SpringBoot的配置文件application.yaml中配置Redis的连接信息,比如ip,启动端口号,密码,数据库等
#配置redis需要指定 host,ip,password
spring:
  redis:
    host: 192.168.226.128  #ip地址
    port: 6381    #启动端口号,默认是6379端口
    password: orange  #Redis密码,也就是在redis.conf中requirepass中配置的
    database: 0  #使用的Redis数据库的下标,默认是第一个,下标为0
  1. 测试连接Redis,使用redisTemplate 或 stringRedisTemplate对象来操作

    – 对于redisTemplate对象中的方法:

    解释:opsForSet :表示是对Redis中Set类型的操作 ,返回一个SetOperations对象,该对象中包括所有对Set类型的操作方法

    ​ opsForValue :表示是对Redis中String类型的操作 ,返回一个ValueOperations对象,该对象中包括所有对String类型的操作方法

    ​ opsForHash :表示是对Redis中Hash类型的操作 ,返回一个SetOperations对象,该对象中包括所有对Hash类型的操作方法

    ​ opsForZSet :表示是对Redis中ZSet类型的操作 ,返回一个SetOperations对象,该对象中包括所有对ZSet类型的操作方法

    ​ opsForList :表示是对Redis中List类型的操作 ,返回一个SetOperations对象,该对象中包括所有对List类型的操作方法

    依此类推 …

    除了这些还包括对Redis的简单操作

    redisTemplate.keys("*")  //查看所有的key
    redisTemplate.delete()   //删除某些key
    redisTemplate.multi()    //开启事务
    redisTemplate.exec()    //执行事务
    redisTemplate.discard() //停止(中断)事务
       ...
    

    – 对于stringRedisTemplate对象中的方法 和 redisTemplate类似:

    ​ opsForValue :表示是对Redis中String类型的操作 ,返回一个ValueOperations****对象,该对象中包括所有对String类型的操作方法 ,同样还包括对Redis的简单操作

    测试代码:

    @SpringBootTest
    class SpringBootRedis05ApplicationTests {
        //直接将这两个对象注入,因为已经在spring容器中了,默认名字就是redisTemplate和stringRedisTemplate
        @Resource
        private RedisTemplate redisTemplate;
    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @Test
        public void testRedis(){
          //使用RedisTemplate添加一个String类型数据到Redis数据库
            redisTemplate.opsForValue().set("testRedisTemplate","Hello,RedisTemplate");
            
          //使用StringRedisTemplate添加一个String类型数据到Redis数据库
            stringRedisTemplate.opsForValue().set("testStringRedisTemplate","Hello,StringRedisTemplate");
            
          //分别获取添加的数据
            System.out.println(redisTemplate.opsForValue().get("testRedisTemplate"));
            System.out.println(stringRedisTemplate.opsForValue().get("testRedisTemplate"));
        }
    }
    
    

​ 输出结果:(连接成功,并且能正常存取值到Redis中)

在Redis中查看数据:

发现问题:使用RedisTemplate对象存入的数据键值对都是显示乱码的,而使用StrringRedisTemplate对象存入的数据键值对都是显示正常的

解释乱码原因
  • 因为任何数据存入到Redis中都是需要先经过序列化的,然后将序列化之后的数据存入,之所以会造成RedisTemaplate对象数据显示乱码,而StringRedisTemaplate对象数据显示正常,根本原因:它们俩默认的 序列化方式不同

  • 测试获取默认的序列化方式(包括对key和value的序列化方式)

@SpringBootTest
class SpringBootRedis05ApplicationTests {
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testRedis(){
        
      // redisTemplate.getConnectionFactory().getConnection().flushDb();
        System.out.println("查看stringRedisTemplate的默认序列化方式");
        System.out.println(stringRedisTemplate.getDefaultSerializer());
        System.out.println(stringRedisTemplate.getKeySerializer());
        System.out.println(stringRedisTemplate.getValueSerializer());
        
        
        System.out.println("查看RedisTemplate的默认序列化方式");
        System.out.println(redisTemplate.getDefaultSerializer());
        System.out.println(redisTemplate.getKeySerializer());
        System.out.println(redisTemplate.getValueSerializer());

    }
}

输出结果:可以看出,这两个对象默认的序列化方式都是jdk的序列化,但是RedisTemplate对于key和value的序列化方式仍然使用jdk的序列化方式,而StringRedisTemplate对于key和value的序列化方式是字符串的序列化

jdk序列化:是将数据变成字节数组后传输,且jdk序列化是不支持跨平台和语言的,也就是先将key和value转换成字节数组后再存到Redis中的,所以显示的不是我们想看的。

解决办法
  • 我们一般使用的序列化都是将key使用string的序列化,而value就是使用json的序列化,将value转换成一个json格式的字符串进行保存

  • 如何修改默认RedisTemplate 的序列化配置?

    源码分析:

在Redis的自动装配类RedisAutoConfiguration中创建了RedisTemplate对象,并注入到Spring容器的

@AutoConfiguration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    //使用@Bean注解将方法返回值注入到spring容器,默认注入的是 RedisTemplate 对象
    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}

也就是说,如果存在一个bean叫做redisTemplate的时候,就不会调用这个方法,也就是该类不会再创建一个redisTemplate对象,所以我们可以自己创建一个叫做redisTemplate的对象,然后修改它的序列化方式,这样就使用我们自己创建的redisTemplate对象来进行对Redis的操作

总结一句话:创建自己的redisTemplate对象来覆盖springboot帮我们创建的,我们自己创建就可以指定序列化方式了

  • 自己创建的配置类:

    package com.example.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.RedisSerializer;
    
    import java.net.UnknownHostException;
    
    //加上@Configuration表示该类是一个配置类
    @Configuration
    public class RedisConfig {
    
        //自己创建RedisTemplate对象并放到spring容器中去
        @Bean
        public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
            // 将redisTemplate 泛型设置为 
            RedisTemplate template = new RedisTemplate();
            // 连接工厂,不必修改
            template.setConnectionFactory(redisConnectionFactory);
            
            //redisTemplate 中的 key、hash的key 采用 String序列化方式
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
    
            //redisTemplate 中的 value、hash的value 采用 Jackson 序列化方式
            template.setValueSerializer(RedisSerializer.json());
            template.setHashValueSerializer(RedisSerializer.json());
            template.afterPropertiesSet();
    
            return template;
        }
    
    }
    
    
  • 运行测试程序

  • 运行结果:

  • 在Redis客户端中查看:

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1040701.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号