Springboot 整合Redis
在Springboot 2.x之后,jedis被替换成了lettuce。
jedis lettuce 对比
jedis:采用直连的方式,多线程操作是不安全的。如果要规避多线程不安全要使用jedis pool连接池。BIO模式
lettuce:采用netty,实例可以在多个线程中共享,不存在线程不安全的情况。可以减少线程数量。NIO模式
Springboot 对Redis的自动配置
自动配置类:org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
//Springboot 为我们自动化初始化了 redisTemplate 模板类;
//如果我们使用并自定义了模板类,则该配置不生效。
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
//Key为String类型的模板类。
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
其中 RedisProperties 指定了Redis在application.yml中的配置项。
配置项 | 默认值 | 注解 |
---|---|---|
spring.redis.client-name | Client name to be set on connections with CLIENT SETNAME. | |
spring.redis.cluster.max-redirects | Maximum number of redirects to follow when executing commands across the cluster. | |
spring.redis.cluster.nodes | Comma-separated list of "host:port" pairs to bootstrap from. This represents an "initial" list of cluster nodes and is required to have at least one entry. | |
spring.redis.database | 0.0 | Database index used by the connection factory. |
spring.redis.host | localhost | Redis 服务器端IP地址 |
spring.redis.jedis.pool.max-active | 8.0 | 在指定的时间,连接池可以分配的最大活跃连接数;设置负数代表无限制. |
spring.redis.jedis.pool.max-idle | 8.0 | Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections. |
spring.redis.jedis.pool.max-wait | -1ms | Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely. |
spring.redis.jedis.pool.min-idle | 0.0 | Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if both it and time between eviction runs are positive. |
spring.redis.jedis.pool.time-between-eviction-runs | Time between runs of the idle object evictor thread. When positive, the idle object evictor thread starts, otherwise no idle object eviction is performed. | |
spring.redis.lettuce.cluster.refresh.adaptive | false | Whether adaptive topology refreshing using all available refresh triggers should be used. |
spring.redis.lettuce.cluster.refresh.period | Cluster topology refresh period. | |
spring.redis.lettuce.pool.max-active | 8.0 | Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit. |
spring.redis.lettuce.pool.max-idle | 8.0 | Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections. |
spring.redis.lettuce.pool.max-wait | -1ms | Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely. |
spring.redis.lettuce.pool.min-idle | 0.0 | Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if both it and time between eviction runs are positive. |
spring.redis.lettuce.pool.time-between-eviction-runs | Time between runs of the idle object evictor thread. When positive, the idle object evictor thread starts, otherwise no idle object eviction is performed. | |
spring.redis.lettuce.shutdown-timeout | 100ms | 关闭延迟时间. |
spring.redis.password | redis 服务器的登录密码. | |
spring.redis.port | 6379.0 | Redis 服务器端端口号 |
spring.redis.sentinel.master | Redis 服务器器名称. | |
spring.redis.sentinel.nodes | Comma-separated list of "host:port" pairs. | |
spring.redis.sentinel.password | Password for authenticating with sentinel(s). | |
spring.redis.ssl | false | 时候开启SSL支持. |
spring.redis.timeout | 链接过期时间。 | |
spring.redis.url | 链接 URL. 包括 host, port,和 password. User被忽略,例如: redis://user:password@example.com:6379 |
实例测试
导入依赖
<!-- 导入springboot 2.x 后默认的redis支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置
spring:
redis:
host: 128.190.252.226
port: 6379
password: hello
database: 0
注意确认以下事项:
- 服务器防火墙是否打开;
- Redis的配置文件 bind 127.0.0.1 需要注释或者改为 bind *
- Redis配置文件 保护模式关闭。
测试
测试String值的写入和读取
@RunWith(SpringRunner.class)
@DataRedisTest
public class SpringbootRedisTest {
@Autowired
RedisTemplate redisTemplate;
@Test
public void testValue(){
redisTemplate.opsForValue().set("name","学习Redis鸭!");
System.out.println(redisTemplate.opsForValue().get("name"));
}
@Test
public void testConnection(){
//获取连接;很少用
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
connection.flushAll();
}
}
通过命令行查看redis服务器端情况:
127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x04name"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get "\xac\xed\x00\x05t\x00\x04name"
"\xac\xed\x00\x05t\x00\x11\xe5\xad\xa6\xe4\xb9\xa0Redis\xe9\xb8\xad\xef\xbc\x81"
Redis中的key Value被编码?
原因分析:
默认我们注入的是RedisTemplate;通过源码分析可以知道:实际上注入的是RedisTemplate<Object,Object>.
但是这样是明显不方便我们日常使用的!
//RedisAutoConfiguration
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
RedisTemplate<Object,Object> 中有一段代码:
boolean defaultUsed = false;
if (this.defaultSerializer == null) {
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
# 其中默认的序列化都是采用的Jdk Serialization
if (this.enableDefaultSerializer) {
if (this.keySerializer == null) {
this.keySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.valueSerializer == null) {
this.valueSerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashKeySerializer == null) {
this.hashKeySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashValueSerializer == null) {
this.hashValueSerializer = this.defaultSerializer;
defaultUsed = true;
}
}
如何解决?
需要我们为Springboot配置一个自定义的RedisTemplate<String,Object>
如果使用Springboot默认的RedisTemplate<Object,Object>那么object 必须实现serializer接口。否则会报错!如下图所示:

对象实现序列化接口后:

自定义RedisTemplate
@Configuration
public class RedisConfig {
@Autowired
ObjectMapper objectMapper;
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
本文由 huzd 创作,采用 知识共享署名4.0 国际许可协议进行许可本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名最后编辑时间
为:
2021/02/10 22:36
跟故宫ggg