1.springboot是怎样自动配置redis的?
1.1.在spring-boot-autoconfigure的包中, org/springframework/boot/spring-boot-autoconfigure/2.5.0/spring-boot-autoconfigure-2.5.0.jar!/META-INF/spring.factories。找到redis的自动配置类:
按Ctrl+鼠标点击进去,如下:
说明:
这里就是springboot自动配置的redisTemplate和stringRedisTemplate的类。也就是说,只要引入spring-boot-starter-data-redis依赖,就会自动配置redisTemplate和stringRedisTemplate的类,在需要使用的地方,直接注入@Autowired private RedisTemplate redisTemplate,就可以使用springboot的redis的对象进行redis操作。
1.2.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2.自动配置生成的redisTemplate和stringRedisTemplate的类,到底做了什么以及拥有什么属性,方法?
继续点击RedisTemplate类进去看看:
进到RedisTemplate类,可以看到defaultSerializer,keySerializer,valueSerializer,hashKeySerializer,hashValueSerializer这五个系列化的属性。
说明:
除了defaultSerializer,其他几个都是null。现在先看下defaultSerializer是什么东西。点击进去,可以看到:
defaultSerializer的默认序列化是JdkSerializationRedisSerializer。
进去后可以看到:
说明:
有个默认的JdkSerializationRedisSerializer系列化,后面还提供了几个其他的序列化方法。但我们更期待的是Jackson2JsonRedisSerializer系列化,这个系列化可以让对象以json的格式保存。
3.怎样自定义配置redis的Jackson2JsonRedisSerializer系列化?
3.1.自定义一个配置类RedisConfig.java
package com.lz.hehuorenservice.common.config;
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 {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<Object>(Object.class);
/* ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);*/
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;
}
}
这个配置类中有几行被注释的代码,需要说明下。
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
这几行代码中:
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
这个代码,会让获取redis的数据时,报序列化失败的错误,如下:
看看redis保存的数据格式是一个数组,而保存进去的是一个对象,并没达到我们期待的json字符串格式的数据:
如果把这个代码去掉:
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
再查看redis的保存和读取的数据,如下:
一起都正常了。