Redis基础—七、springboot整合redis

一、准备工作

我们在springboot中操作数据主要使用的是springdata,里面包含jdbc,mybatis,mongodb等等。

在springboot集合redis的过程中,我们也要使用spring-data进行一个配置的操作。

首先我们新建一个springboot项目,把相关的包导一下,redis的包在Nosql中,顺便web和一些开发工具也导进来。

多服务器 spring 读信息到redis中_spring boot

然后我们点进去redis-starter的源码看一下,发现了惊天大秘密。

多服务器 spring 读信息到redis中_序列化_02

我们发现starter里面居然没有配置jedis,官方推荐的咋不见了,咋换成这个lettuce了。

首先我们看看这两个的本质区别:

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

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

所以说为了解决高并发下的操作,springboot在2之后就是用了lettuce作为内核。

二、撸源码,康原理

首先我们看看spring帮我们做了啥,看一下

多服务器 spring 读信息到redis中_spring boot_03

lib下找一下springFactories,里面找到redis的自动配置。

多服务器 spring 读信息到redis中_spring_04

我们发现spring为我们自动配置了两个模板

多服务器 spring 读信息到redis中_java_05

在默认的情况下,如果没有配置redisTemplate以及StringRedisTemplate,这两个模板就会生效。

其中上面的那个是所有类型通用的,泛型传入两个object类,下面是string类专用的。我们点进去上面的RedisPropeties.class看看它为我们配置了哪些属性值。

private int database = 0;       #选择第几个库

	/**
	 * Connection URL. Overrides host, port, and password. User is ignored. Example:
	 * redis://user:password@example.com:6379
	 */
	private String url;        
	/**
	 * Redis server host.
	 */
	private String host = "localhost";       

	/**
	 * Login username of the redis server.
	 */
	private String username;            

	/**
	 * Login password of the redis server.
	 */
	private String password;              

	/**
	 * Redis server port.
	 */
	private int port = 6379;          

	/**
	 * Whether to enable SSL support.
	 */
	private boolean ssl;

	/**
	 * Read timeout.
	 */
	private Duration timeout;

	/**
	 * Connection timeout.
	 */

这里截取了一部分常用的,我们发现常用的信息诸如端口号啊,用户名啥的,当然我们可以自己配

那我们去修改一下,相关的信息,主要修改一下主机名就好了!

spring.redis.host= xxxx

之后再测试类编写一手很简单的代码

redisTemplate.getConnectionFactory().getConnection().flushDb();
        redisTemplate.opsForValue().set("jj","zjj");
        System.out.println(redisTemplate.opsForValue().get("jj"));

大家如果redis语句学好的话这块必然是没啥问题的。

多服务器 spring 读信息到redis中_spring boot_06

输出成功!去服务器上看看。

我们输出keys *看一下

多服务器 spring 读信息到redis中_spring boot_07

发现这个key不大一样啊!

这个是因为其默认template的序列器与redis服务器上的不大一致,导致会有些编码无法识别,这时我们就需要重写下template。

三、自定义template以及RedisUtil

由于我们再序列化中遇到了一些不知到咋回事儿的编码,我们要自定义一个template.

这里我们创建一个RedisConf配置类,我们拿一个现成人家给咱配好的。

package com.dll.springredis.conf;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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 RedisConf {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);


        //更改默认的序列化类为Jackson2JsonRedisSerializer
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //json序列化配置
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectJackson2JsonRedisSerializer.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用String序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value的序列化方式采用jackson
        template.setValueSerializer(objectJackson2JsonRedisSerializer);
        //hash的value序列化方式采用jackson
        template.setHashValueSerializer(objectJackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

我们可以看见了与value相关的序列器已经变成了Jackson2JsonRedisSerializer,我们再次测试一下原来的代码。

这里我们传进去一个对象试试。

我们定义一个User类,然后将其进行序列化。


@Data
@AllArgsConstructor
@NoArgsConstructor

public class User implements Serializable {
    private String name;
    private int age;
}

测一下。

@Test
void Test2(){
    redisTemplate.opsForValue().set("myjj",new User("zjj",21));
    System.out.println(redisTemplate.opsForValue().get("myjj"));
}

多服务器 spring 读信息到redis中_java_08

没啥问题。

多服务器 spring 读信息到redis中_spring boot_09

在我们真实的企业开发中,经常会将经常使用的模块打包成一个Utils,Utils中调用原生的接口方法并进行一些操作,比如说异常的处理等等等。

这里我们也拿一个Utils。