springboot整合redis、重写配置、源码浏览
SpringBoot整合SpringBoot操作数据:是封装在Spring-data中的,jpa、jdbc、mongodb、redis在SpringBoot2.x以后与原来使用的jedis被替换成来看lettuce,底层已经不使用jedis了jedis:采用的直连,多个线程操作的话,不安全,要提高安全性要使用jedis pool连接池lettuce:采用netty,高性能网络框架,异步请求,实例在
SpringBoot整合
SpringBoot操作数据:是封装在Spring-data中的,jpa、jdbc、mongodb、redis
在SpringBoot2.x以后与原来使用的jedis被替换成来看lettuce,底层已经不使用jedis了
- jedis:采用的直连,多个线程操作的话,不安全,要提高安全性要使用jedis pool连接池
- lettuce:采用netty,高性能网络框架,异步请求,实例在多线程中可以共享,不存在线程不安全的情况,dubbo底层也是用netty,可以减少线程数量,更像NIO
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
原理讲解
-
SpringBoot所有配置类,都会有一个自动配置类
-
-
自动配置类都会绑定一个properties配置文件
-
RedisAutoConfiguation
-
-
启动配置类中有一个RedisProperties配置类
-
-
里面有很多以前缀spring.redis开头的配置,可以在application中配置
-
如host、password、、配置
-
RedisAutoConfiguation中封装了两个Bean
-
RedisTemplate
-
@Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; }
-
没有过多的设置,Redis的对象都是需要序列化的
-
两个泛型都是object,后面使用需要强制转换
-
靠自己重写config来替换这个template
-
-
StringRedisTamplate
- 大部分情况下String类型是最常用的,就会多一个stringRedisTemplate
-
-
@ConditionalOnMissingBean(name = "redisTemplate") //重写一个redisTemplate就能替换掉这个bean
整合实现
- 导入依赖
- 配置连接
- 测试
实现
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
-
根据在properties中看到的配置参数,以spring.redis为prefix的配置
-
但是建议使用lettuce
-
在redisTemplate的parameter中需要给入一个RedisConnectionFactory
-
-
有两个方法实现了这个接口
-
在Jedis中有多个爆红,没下载完整
-
-
lettuce中下载完整,为了避免不必要的错误,建议使用lettuce,默认生效
-
测试
-
-
注入,RedisTamplate,里面有ops,表示operations 操作
-
操作value字符串,hash、list、set、cluter集群、、、
-
操作的几种数据类型,有些操作也直接拿出来了,可以直接调用,其他比较细化的操作就要进入各自的数据类型的操作
-
@Test void contextLoads() { redisTemplate.opsForValue().set("name","haoyun"); System.out.println(redisTemplate.opsForValue().get("name")); RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); connection.flushAll(); connection.close(); }
-
能直接操作也能获取连接
-
127.0.0.1:6379> keys * 1) "\xac\xed\x00\x05t\x00\x04name" 127.0.0.1:6379>
-
但是会出现乱码
-
Redis的对象都需要序列化serialization
-
默认的序列化是JDK序列化,可能要使用JSON来序列化
-
需要自己来定义配置类
-
创建对象时需要序列化、implement Serializable
-
@Test void test2() throws JsonProcessingException { User user = new User(); // String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); }
-
直接将user给入会产生defaultSerializer序列化问题
-
@Test void test2() throws JsonProcessingException { User user = new User(); // String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); }
-
直接给入user对象,会报错DefaultSerializer错误
-
-
将对象序列化,或通过fastjson的方法专为string类型
-
正式的开发一般通过json来传不会直接传对象
-
虽然不报错了,但是存储的数据还是乱码
-
127.0.0.1:6379> keys * 1) "\xac\xed\x00\x05t\x00\x04name" 2) "\xac\xed\x00\x05t\x00\x04user" 127.0.0.1:6379>
-
默认序列化是JDKSerializer
-
RedisSerializer有多种实现方法
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hnhHrbf-1606724738964)(…/…/…/Library/Application Support/typora-user-images/image-20201123202648831.png)]
-
选取一个实现方法,给setKeySerializer
-
template.setKeySerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
-
多使用cmd+p查看方法需要的parameter,给进去就好
-
RedisConfig
-
package com.haoyun.redisspringboot.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.net.UnknownHostException; @Configuration @SuppressWarnings("all") //镇压所有警告 public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 默认的连接配置 template.setConnectionFactory(redisConnectionFactory); // 序列化配置 // new 一个Jackson序列化对象,用于后面的设置 Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 用于转义 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 创建string的序列化 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // string的key和hash的key都采用string的序列化 // value都采用Jackson的序列化 //key采用string序列化方式 template.setKeySerializer(stringRedisSerializer); //hash的key采用string序列化方式 template.setHashKeySerializer(stringRedisSerializer); //value采用Jackson序列化方式 template.setValueSerializer(objectJackson2JsonRedisSerializer); //hash的value采用Jackson序列化方式 template.setHashValueSerializer(objectJackson2JsonRedisSerializer); return template; } }
-
测试
-
package com.haoyun.redisspringboot; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.haoyun.redisspringboot.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; @SpringBootTest class RedisSpringbootApplicationTests { @Autowired @Qualifier("redisTemplate") private RedisTemplate redisTemplate; @Test void test1() throws JsonProcessingException { User name1 = new User("name", 3); String name = new ObjectMapper().writeValueAsString(name1); redisTemplate.opsForValue().set("key1", name); System.out.println(redisTemplate.opsForValue().get("key")); } }
-
通过这样的序列化之后key就不会乱码了,但是在企业开发中一般不直接以原生的编写,将常用的操作封装为RedisUtils,自己写一些工具类来使用
-
在工具类中应该加入一些容错操作,能抛出异常
-
在公司能看到一些封装的RedisUtils

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)