最近在研究redis,以及spring data對redis的支援發現了一個奇怪的現象
先說現象吧,通過redisTemplate下的opsForHash方法儲存hash類型的值,操作成功以後,去redis控制台顯示keys * 的時候,發現一個奇怪的現象,插入的hash類型的key前面會有一堆的\xac\xed\x00\x05t\x00\tb 這種東西,見圖1
(圖1)
看見了嗎。就是第二行那一串自己冒出來的東西,分析spring-data的org.springframework.data.redis.core.RedisTemplate原始碼以後發現:
[java] view plain copy private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer(); private RedisSerializer keySerializer = null; private RedisSerializer valueSerializer = null; private RedisSerializer hashKeySerializer = null; private RedisSerializer hashValueSerializer = null; private RedisSerializer<String> stringSerializer = new StringRedisSerializer();
發現了一個:
[java] view plain copy private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
因為spring操作redis是在jedis用戶端基礎上進行的,而jedis用戶端與redis互動的時候協議中定義是用byte類型互動,jedis中提供了string類型轉為byte[]類型,但是看到spring-data-redis中RedisTemplate<K, V>在操作的時候k,v是泛型的,所以RedisTemplate中有了上面那段代碼,在沒有特殊定義的情況下,spring預設採用defaultSerializer = new JdkSerializationRedisSerializer();來對key,value進行序列化操作,在經過查看JdkSerializationRedisSerializer中對序列化的一系列操作,發現如下代碼:
[java] view plain copy private Converter<Object, byte[]> serializer = new SerializingConverter(); public byte[] serialize(Object object) { if (object == null) { return SerializationUtils.EMPTY_ARRAY; } try { return serializer.convert(object); } catch (Exception ex) { throw new SerializationException("Cannot serialize", ex); } }
序列化支援的是Object對象,調用了SerializingConverter類下的convert方法轉換對象,轉換對象的方法是:
[java] view plain copy private final Serializer<Object> serializer; /** * Serializes the source object and returns the byte array result. */ public byte[] convert(Object source) { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128); try { this.serializer.serialize(source, byteStream); return byteStream.toByteArray(); } catch (Throwable ex) { throw new SerializationFailedException("Failed to serialize object using " + this.serializer.getClass