写点什么

SpringBoot 整合 Redis,再也不用求别人了

作者:@下一站
  • 2022-12-17
    陕西
  • 本文字数:3130 字

    阅读完需:约 10 分钟

SpringBoot 整合 Redis

在 SpringBoot 中一般使用 RedisTemplate 提供的方法来操作 Redis。那么使用 SpringBoot 整合 Redis

需要那些步骤呢。

1.JedisPoolConfig(这个是配置连接池)

2.RedisConnectionFactory(这个是配置连接信息,这里的 RedisConnectionFactory 是一个接口,

我们需要使用它的实现类,在 SpringD Data Redis 方案中提供了一下四种工厂模型)

JredisConnectionFactory

JedisConnectionFactory

LettuceConnectionFactory

SrpConnectionFactory

3.RedisTemplate

1、添加启动器

<!--redis-->       <dependency>           <groupId>org.springframework.boot</groupId>           <artifactId>spring-boot-starter-data-redis</artifactId>       </dependency>
复制代码


2、配置连接信息

spring:    redis:      host: 127.0.0.1       port: 6379      password: 123456      jedis:        pool:          max-active: 8          max-wait: -1          max-idle: 500          min-idle: 0      lettuce:        shutdown-timeout: 0
复制代码


3、测试

@RunWith(SpringRunner.class)@SpringBootTestpublic class Test_1{    @Autowired    private RedisTemplate<String,String>redisTemplate;
@Test public void set(){ redisTemplate.opsForValue().set("myKey","myValue"); System.out.println(redisTemplate.opsForValue().get("myKey")); }}
复制代码


4、查看结果


5、序列化器

这里先说一下 Spring 提供了那些序列化器(各自作用自行百度,这里不再赘述)

Jackson2JsonRedisSerializer

JdkSerializationRedisSerializer

OxmSerializer

StringRedisSerializer

GenericToStringRedisSerializer

GenericJackson2JsonRedisSerializer

然后以下是一些问题需要搞清楚

为什么需要序列化?

你要记住一句话,在 JAVA 中,一切皆对象,而将对象的状态信息转为存储或传输的形式需要序列化。

为什么前面的代码没有设置序列化?

原因是是因为我们使用了 @AutoWired,IOC 容器为我们选择了 StringRedisTemplate 类来注入

以下是单步调试的截图


这里是 RedisTemplate 的继承关系图


然后我们跟踪源码可以发现StringRedisTemplate.java

	public StringRedisTemplate() {		setKeySerializer(RedisSerializer.string());		setValueSerializer(RedisSerializer.string());		setHashKeySerializer(RedisSerializer.string());		setHashValueSerializer(RedisSerializer.string());	}
复制代码

RedisSerializer.java

static RedisSerializer<String> string() {		return StringRedisSerializer.UTF_8;	}
复制代码

StringRedisSerializer.java

public static final StringRedisSerializer UTF_8 = new StringRedisSerializer(StandardCharsets.UTF_8);
复制代码

StringRedisTemplate 默认选择的 StringRedisSerializer 序列化器

  • 那假如我们把 Value 的类型改为 Object 呢

@RunWith(SpringRunner.class)@SpringBootTestpublic class Test_1{    @Resource    private RedisTemplate<String,Object>redisTemplate;
@Test public void set(){ redisTemplate.opsForValue().set("myKey","myValue"); System.out.println(redisTemplate.opsForValue().get("myKey")); }}
复制代码

注意:这里继续使用 @AutoWired 会报错,需要使用 @Resource,这两个注解的区别在前者是根据类型后者

是根据名字,具体区别自行查资料(这里说一下为什么会报错:@AutoWired 找不到该类型

<String,Object>的 Bean 因为根本没有。使用 @Resource 直接注入的是 RedisTemplate)


然后运行代码,我们去看 RedisManeger


咦?怎么会这样?这是因为没有设置序列化器,RedisTemplate 选择了默认的序列化器JdkSerializationRedisSerializer官方文档是这样说的:RedisTemplate (Spring Data Redis 2.1.4.RELEASE API)

Performs automatic serialization/deserialization between the given objects and

the underlying binary data in the Redis store. By default, it uses Java serialization

for its objects (through JdkSerializationRedisSerializer ).

For String intensive operations consider the dedicated StringRedisTemplate.


6、配置序列化器

说了这么多,那么我们如何自己设置序列化器呢,方法有很多种,比如比较简单的就是

方法 1

@RunWith(SpringRunner.class)@SpringBootTestpublic class Test_1{    @Resource    private RedisTemplate<String,Object>redisTemplate;    @Test    public void set(){        redisTemplate.setKeySerializer(RedisSerializer.string());        redisTemplate.setKeySerializer(RedisSerializer.string());        //或者        //redisTemplate.setKeySerializer(new StringRedisSerializer());        //redisTemplate.setKeySerializer(new StringRedisSerializer());        redisTemplate.opsForValue().set("myKey","myValue");        System.out.println(redisTemplate.opsForValue().get("myKey"));    }}
复制代码

有的时候每次这样设置比较烦人,那么就采用配置类(更多的时候采用这种方法)

方法 2(这样的话,测试类就应该使用 @AutoWired 了哦)

@Configurationpublic class RedisConfig{    @Bean    public RedisTemplate<String,Object>redisTemplate(RedisConnectionFactory factory){        RedisTemplate<String,Object>template=new RedisTemplate<>();        //关联        template.setConnectionFactory(factory);        //设置key的序列化器        template.setKeySerializer(new StringRedisSerializer());        //设置value的序列化器         template.setValueSerializer(new StringRedisSerializer());        return template;    }}
复制代码

为什么说更多的时候采用这种方法呢,实际情况中可能有多种需求,泛型各不相同,比如有<String,User>

直接在 Config 类里面在加一个方法就行。

7、完整例子(将实体类以 JSON 的形式储存到 Redis 中)

1、先给出 entity(记住实体要序列化一定要实现 Serializable 接口)

@Datapublic class Days implements Serializable {    private String openId;    private String daysId;    //每天的标题    private String title;    //代办事项的数量    private int itemNumber;    //日程    private String date;}
复制代码

2、然后在配置类中设置序列化器

@Configurationpublic class RedisConfig{    @Bean    public RedisTemplate<String, Days>redisTemplate(RedisConnectionFactory factory){        RedisTemplate<String,Days>template=new RedisTemplate<>();        //关联        template.setConnectionFactory(factory);        //设置key的序列化器        template.setKeySerializer(new StringRedisSerializer());        //设置value的序列化器        template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Days.class));        return template;    }}
复制代码

3、测试类

@RunWith(SpringRunner.class)@SpringBootTestpublic class RedisTest {
@Autowired private RedisTemplate<String,Days> redisTemplate; private Days d; @Before public void before(){ d=new Days(); d.setDate("123"); d.setDaysId("456"); d.setItemNumber(123); d.setOpenId("dawda"); d.setTitle("title"); } @Test public void testSet(){ this.redisTemplate.opsForValue().set("days",d); System.out.println((redisTemplate.opsForValue().get("days"))); }}
复制代码

4、运行结果


测试成功

发布于: 刚刚阅读数: 4
用户头像

@下一站

关注

懒人 2020-11-22 加入

都是黄泉预约客,何必难为每一天,执念太强,无法豁然。

评论

发布
暂无评论
SpringBoot 整合 Redis,再也不用求别人了_redis_@下一站_InfoQ写作社区