先说一下怎么配置不同的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;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
原理: 这里先贴一段源码,但是各位同学也必须点进去看一看,才能明白:
上图源码是 LettuceConnection 的其中4个个构造函数,说起来是4个,但是各位仔细看就他妈是一个构造函数啊。
这几个构造函数的第一个参数都是RedisConfiguration,第二个参数是LettuceClientConfiguration,看到这两个类的名字,顿时应该猜出7,8分了吧。就是 普通配置和客户端配置。
先看 第一个参数 RedisConfiguraion:
上图是它的实现类,完全验证了上张源码图的说法,都是RedisConfiguration,只不过不同的实现有不同的功能,我刚才的createLettuceConnectionFactory方法是使用了RedisStandaloneConfiguration实现,因为这个是标准的实现,设置的 密码 ,端口,IP这些基本数据,其它的实现比如 RedisSentinelConfiguraon就是典型的 哨兵模式实现,想想我们以前使用SpringBoot配置redis集群的时候,应该就是它和RedisClusterConfiguration在运作了。
好,说完了RedisConfiguration,再说第二个参数 LettuceClientConfiguration:
故名思意,客户端配置了,也是先贴张图片:
这是它的实现,其中我刚才 createLettuceConnectionFactory 方法里使用的是LettucePoolingClientConfiguration 子接口。
上图就是我 createLettuceConnectionFactory 方法里设置 TimeOut和 shutdowntTimeOot的依据,它的作用就是用来设置客户端参数的。
看到这里明白了吧,非常简单,只是我在看源码的时候,感觉非常的绕,Spring的源码就是这样,它的思想就是掩盖实现,约定大于配置,让你更关注逻辑代码,而不是这些原理。看这些实现源码往往是训练你的设计模式和对底层原理的认识,让你知道为什么这样写,而不是为了设计模式而写设计模式。
路漫漫,求索不断呀。。。。。。。。。。。。。。。。。。。。