public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader classLoader) {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
registerDefaultConverters(conversionService);
return new RedisCacheConfiguration(Duration.ZERO, true, true, CacheKeyPrefix.simple(),
SerializationPair.fromSerializer(RedisSerializer.string()),
SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
}
可以看到对value的序列化是SerializationPair.fromSerializer(RedisSerializer.java(classLoader))
,我们继续追看RedisSerializer.java(classLoader)
的返回值:
static RedisSerializer<Object> java(@Nullable ClassLoader classLoader) {
return new JdkSerializationRedisSerializer(classLoader);
}
默认使用的是JDK的序列化机制,这就使得,我们存入redis中的数据类似于下面这样:
127.0.0.1:6379> get "emp::10001"
"\xac\xed\x00\x05sr\x00\x1acom.nl.cache.bean.Employee\x1f\x10\x81\"\xbd\xdc\x8c\x9c\x02\x00\x05L\x00\x03dIdt\x00\x13Ljava/lang/Integer;L\x00\x05emailt\x00\x12Ljava/lang/String;L\x00\x06genderq\x00~\x00\x01L\x00\x02idq\x00~\x00\x01L\x00\blastNameq\x00~\x00\x02xppt\x00\x0echo@unkown.comsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01sq\x00~\x00\x05\x00\x00'\x11t\x00\x03cho"
这让我们在存入数据后,想要比对时,不容易查看。所以我们决定,让以json的形式进行序列化。
org.springframework.data.redis.cache.RedisCacheManager
的create()方法public static RedisCacheManager create(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
return new RedisCacheManager(new DefaultRedisCacheWriter(connectionFactory),
RedisCacheConfiguration.defaultCacheConfig());
}
我们只需修改RedisCacheManager构造方法的第二个参数RedisCacheConfiguration.defaultCacheConfig()
,它的返回值是一个RedisCacheConfiguration类型,自然想到new一个就可以了,但发现它的构造方法是私有的,有两种方法,一种就是仿照这个类,写一个相同的类,把构造方法改为public,另一个就是通过反射的方式,鉴于再写一个类,冗余比较多,就决定用反射。
参考文章开头第一段代码,创建RedisCacheConfiguration
@Bean
public RedisCacheManager customizedCacheManager(RedisConnectionFactory connectionFactory) throws InvocationTargetException, IllegalAccessException, InstantiationException {
//对 对象类型(employee)和string类型的序列化
Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Employee.class);
Jackson2JsonRedisSerializer<String> keySerializer = new Jackson2JsonRedisSerializer<>(String.class);
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
RedisCacheConfiguration.registerDefaultConverters(conversionService);
RedisCacheConfiguration redisCacheConfiguration = null;
Constructor[] constructors = RedisCacheConfiguration.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
constructor.setAccessible(true);
if(constructor.getParameterTypes().length==7){//因为只有构造方法,所以判断方式比较随意
redisCacheConfiguration = (RedisCacheConfiguration) constructor.newInstance(Duration.ZERO, true, true, CacheKeyPrefix.simple(), RedisSerializationContext.SerializationPair.fromSerializer(keySerializer), RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer),conversionService);
}
}
assert redisCacheConfiguration != null;
//通过RedisCacheManagerBuilder来创建RedisCacheManager,也可以直接new
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(connectionFactory).cacheDefaults(redisCacheConfiguration).build();
}
将该组件注册到spring容器中即可。
这样,我们再次通过后台程序缓存写入redis中时,就可以看到下面的形式:
127.0.0.1:6379> keys *
1) "\"emp::10001\""
127.0.0.1:6379> get "\"emp::10001\""
"{\"id\":10001,\"lastName\":\"cho\",\"email\":\"cho@unkown.com\",\"gender\":1,\"dId\":null}"