Redis-03(整合springboot)

SpringBoot整合

springboot操作数据:springdata jpa jdbc mongodb redis
Springdata也是和SpringBoot齐名的项目

源码分析

@Bean
@ConditionalOnMissingBean(name = "redisTemplate") 
// 我们可以自己定义一个redisTemplate来替换这个默认的!
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
// 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 <String, Object>
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}
@Bean
@ConditionalOnMissingBean // 由于 String 是redis中最常使用的类型,所以说单独提出来了一个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

整合测试

  1. 导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

springboot 2.x后 ,原来使用的 Jedis 被 lettuce 替换。

jedis:采用的直连,多个线程操作的话,是不安全的。如果要避免不安全,使用jedis pool连接池!更像BIO模式

lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式

我们在学习SpringBoot自动配置的原理时,整合一个组件并进行配置一定会有一个自动配置类xxxAutoConfiguration,并且在spring.factories中也一定能找到这个类的完全限定名。Redis也不例外。
image
还存在一个RedisProperties类
image
@ConditionalOnClass注解中有两个类是默认不存在的,所以Jedis是无法生效的然后在看Lettuec:
image
生效
我们回到RedisAutoConfiguration
image
只有两个简单的Bean

  • RedisTemplate
  • StringRedisTemplate
    当看到xxxTemplate时可以对比RestTemplate,SqlSessionTemplate通过使用这些Template来简介操作组件,这两个也不例外,分别用于操作Redis和Redis中的String数据类型.

在RedisTemplate上也有一个条件注解,说明我们是可以对其定制化的

我们需要知道如何编写配置文件然后连接Redis,就需要阅读RedisProperties

  1. 编写配置文件application.xml中配置
# 配置redis
spring.redis.host=39.99.xxx.xx
spring.redis.port=6379
  1. 使用RedisTemplate(新建一个config.RedisConfig.java)
    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;
 @Test
    void contextLoads() {
        //在企业开发中,80%都不会使用原生的方式编写代码,我们可以使用RedisUtils去编写代码

        //opsForValue:操作字符串,类似于String
        //opsForList:操作List,类似于List
        //opsForSet:操作set,类似于set
        //opsForHash:操作hash,类似于hash
        //opsForZset:操作zset,类似于zset
        //opsForGeo:操作geo,类似于geo
        //...

        //除了基本的操作,常用的方法都可以直接通过redisTemplate操作,比如事务和CRUD
        //RedisConfig.flushDb();
        redisTemplate.opsForValue().set("key","sli");
        System.out.println(redisTemplate.opsForValue().get("key"));

    }
  1. 测试结果,回到Redis客户端查看数据的时候发现都是乱码,是由于没有序列化造成的,RedisTemplate内部的序列化配置是这样的
    image
    默认的序列化器采用JDK序列化器
    后续我们定制RedisTemplate就可以对其进行修改。
    RedisSerializer提供了多种序列化方案:
    image
    我们自己编写RedisTemplate来使原来的失效
package com.sli.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;
@Configuration
public class RedisConfig {
    // 固定模板在企业中,拿去就可以直接使用!
    // 自己定义了一个 RedisTemplate
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 为了开发方便,一般直接使用 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String,
                Object>();
        template.setConnectionFactory(factory);
        // Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}
  1. 编写测试代码
 @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

 @Test
    public void test(){

        User user = new User("sli", 2);
        redisTemplate.opsForValue().set("user",user);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }
  • 通过这样的序列化之后key就不会乱码了,但是在企业中开发一般不直接写原生的代码,将常用的操作封装为RedisUtils,自己写一些工具类来调用,工具类中能加入一些容错操作,抛出异常.
posted @ 2021-10-11 18:38  1_f  阅读(28)  评论(0)    收藏  举报