先说一下怎么配置不同的redis源吧.

配置文件 application.properties:

#########-------------------------------------->  Redis 配置,因为是不同的数据库,
							所以需要配置不同的 redisTemplate
############设置缓存为 Redis
spring.cache.type=redis

##cache 数据库
redis.cache.database=0

#Session 数据库
redis.session.database=1

redis.host=主机IP(localhost)
redis.port=6379
redis.password=密码

##最大连接数
redis.lettuce.pool.max-active=8
##连接的最大等待阻塞的时间
redis.lettuce.pool.max-wait=10000
##最大和最小空闲连接
redis.lettuce.pool.max-idle=4
redis.lettuce.pool.min-idle=0
##连接超时的时间
redis.timeout=10000
#关闭时的超时时间
redis.lettuce.shutdown-timeout=4000

如果是单数据源配置就没这么麻烦了。但是这里,一个数据库作为 cache ,一个作为 session,所以自然是多数据源配置。

/**
     * 配置 Jackson2JsonRedisSerializer 序列化器,在配置 redisTemplate需要用来做k,v的
     * 序列化器
     */
     static  Jackson2JsonRedisSerializer getJackson2JsonRedisSerializer(){
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = null;
        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);
        return jackson2JsonRedisSerializer;
    }

    static final Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
            getJackson2JsonRedisSerializer();
/**
     * 自定义LettuceConnectionFactory,这一步的作用就是返回根据你传入参数而配置的
     * LettuceConnectionFactory,
     * 也可以说是LettuceConnectionFactory的原理了,
     * 后面我会详细讲解的,各位同学也可先自己看看源码

		这里定义的方法 createLettuceConnectionFactory,方便快速使用
     */
    private  LettuceConnectionFactory createLettuceConnectionFactory(
            int dbIndex, String hostName, int port, String password,
            int maxIdle,int minIdle,int maxActive,
            Long maxWait, Long timeOut,Long shutdownTimeOut){
            
        //redis配置
        RedisConfiguration redisConfiguration = new 
        							RedisStandaloneConfiguration(hostName,port);
        ((RedisStandaloneConfiguration) redisConfiguration).setDatabase(dbIndex);
        ((RedisStandaloneConfiguration) redisConfiguration).setPassword(password);

        //连接池配置
        GenericObjectPoolConfig genericObjectPoolConfig =
 												 new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);

        //redis客户端配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder 
    	  		  builder =  LettucePoolingClientConfiguration.builder().
         				 commandTimeout(Duration.ofMillis(timeOut));
                
        builder.shutdownTimeout(Duration.ofMillis(shutdownTimeOut));
        builder.poolConfig(genericObjectPoolConfig);
        LettuceClientConfiguration lettuceClientConfiguration = builder.build();

        //根据配置和客户端配置创建连接
        LettuceConnectionFactory lettuceConnectionFactory = new 
        LettuceConnectionFactory(redisConfiguration,lettuceClientConfiguration);
        lettuceConnectionFactory .afterPropertiesSet();

        return lettuceConnectionFactory;
    }
/*
     * 读取配置文件里的redis配置
     */
     	/cache的数据库索引
    @Value("${redis.cache.database}")
    private Integer cacheDatabaseIndex;

	//sessiondb的数据库索引
    @Value("${redis.session.database}")
    private Integer sessionDatabaseIndex;

    @Value("${redis.host}")
    private String hostName;

    @Value("${redis.port}")
    private Integer port;

    @Value("${redis.password}")
    private String password;

    @Value("${redis.lettuce.pool.max-idle}")
    private Integer maxIdle;

    @Value("${redis.lettuce.pool.min-idle}")
    private Integer minIdle;

    @Value("${redis.lettuce.pool.max-active}")
    private Integer maxActive;

    @Value("${redis.lettuce.pool.max-wait}")
    private Long maxWait;

    @Value("${redis.timeout}")
    private Long timeOut;

    @Value("${redis.lettuce.shutdown-timeout}")
    private Long shutdownTimeOut;

下面就是 seesionRedis和cacheRedis的配置了,其实就是根据上面的createLettuceConnectionFactory方法和配置属性来构造不同的 LettuceConnectionFactory
从而实现不同的RedisTemplate,然后使用上面所说过的序列化器配置redisTemplate的 key,value序列化方式

/**
     *  配置 cache RedisTemplate
     * @return  RedisTemplate<String,Serializable>r
     */
    @Bean(value="cacheRedisTemplate")
    public RedisTemplate<String,Object> getCacheRedisTemplate(){
  		  //创建客户端连接
        LettuceConnectionFactory lettuceConnectionFactory =
                createLettuceConnectionFactory
                        (cacheDatabaseIndex,hostName,port,password,maxIdle,minIdle,maxActive,maxWait,timeOut,shutdownTimeOut);
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        /**
         * 使用 String 作为 Key 的序列化器,使用 Jackson 作为 Value 的序列化器
         */
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

///

    /**
     *  配置Session RedisTemplate
     * @return  RedisTemplate<String,Serializable>r
     */
    @Bean(value="sessionRedisTemplate")
    public RedisTemplate<String,Object> getSessionRedisTemplate(){
        //创建客户端连接
        LettuceConnectionFactory lettuceConnectionFactory =
                createLettuceConnectionFactory
                        (sessionDatabaseIndex,hostName,port,password,maxIdle,minIdle,maxActive,maxWait,timeOut,shutdownTimeOut);
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        /**
         * 使用 String 作为 Key 的序列化器,使用 Jackson 作为 Value 的序列化器
         */
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

原理: 这里先贴一段源码,但是各位同学也必须点进去看一看,才能明白:

lettuce stringRedisTemplate 如何配置连接信息 lettuce连接池配置_序列化

上图源码是 LettuceConnection 的其中4个个构造函数,说起来是4个,但是各位仔细看就他妈是一个构造函数啊。

这几个构造函数的第一个参数都是RedisConfiguration,第二个参数是LettuceClientConfiguration,看到这两个类的名字,顿时应该猜出7,8分了吧。就是 普通配置和客户端配置。

先看 第一个参数 RedisConfiguraion:

lettuce stringRedisTemplate 如何配置连接信息 lettuce连接池配置_redis_02


上图是它的实现类,完全验证了上张源码图的说法,都是RedisConfiguration,只不过不同的实现有不同的功能,我刚才的createLettuceConnectionFactory方法是使用了RedisStandaloneConfiguration实现,因为这个是标准的实现,设置的 密码 ,端口,IP这些基本数据,其它的实现比如 RedisSentinelConfiguraon就是典型的 哨兵模式实现,想想我们以前使用SpringBoot配置redis集群的时候,应该就是它和RedisClusterConfiguration在运作了。好,说完了RedisConfiguration,再说第二个参数 LettuceClientConfiguration:

故名思意,客户端配置了,也是先贴张图片:

lettuce stringRedisTemplate 如何配置连接信息 lettuce连接池配置_SpringBoot redis配置原理_03


这是它的实现,其中我刚才 createLettuceConnectionFactory 方法里使用的是LettucePoolingClientConfiguration 子接口。

lettuce stringRedisTemplate 如何配置连接信息 lettuce连接池配置_SpringBoot redis配置原理_04


上图就是我 createLettuceConnectionFactory 方法里设置 TimeOut和 shutdowntTimeOot的依据,它的作用就是用来设置客户端参数的。

看到这里明白了吧,非常简单,只是我在看源码的时候,感觉非常的绕,Spring的源码就是这样,它的思想就是掩盖实现,约定大于配置,让你更关注逻辑代码,而不是这些原理。看这些实现源码往往是训练你的设计模式和对底层原理的认识,让你知道为什么这样写,而不是为了设计模式而写设计模式。

路漫漫,求索不断呀。。。。。。。。。。。。。。。。。。。。