redisTemplate,stringRedisTemplate序列化問題

今天遇到一個奇怪的bug,就是redisTemplate獲取不到值,而stringRedisTemplate可以獲取得到,執(zhí)行代碼就是以下

System.out.println(redisTemplate.opsForValue().get("name1"));
System.out.println(stringRedisTemplate.opsForValue().get("name1"));

debug打斷點(diǎn)跟進(jìn)去,DefaultValueOperations.java

public V get(Object key) {

        return execute(new ValueDeserializingRedisCallback(key) {

            @Override
            protected byte[] inRedis(byte[] rawKey, RedisConnection connection) {
//此處打開Evaluate Expression工具,計算rawKey.length=="name".getBytes().length,返回結(jié)果為false,可以定位問題在編碼問題上
                return connection.get(rawKey);
            }
        }, true);
    }

繼續(xù)debugger,可以到以下AbstractOperations.java

// utility methods for the template internal methods
    abstract class ValueDeserializingRedisCallback implements RedisCallback<V> {
        private Object key;

        public ValueDeserializingRedisCallback(Object key) {
            this.key = key;
        }

        public final V doInRedis(RedisConnection connection) {
         //此處是將key序列化為byte[]的,繼續(xù)跟到rawKey方法中
            byte[] result = inRedis(rawKey(key), connection);
            return deserializeValue(result);
        }

        @Nullable
        protected abstract byte[] inRedis(byte[] rawKey, RedisConnection connection);
    }

繼續(xù)跟到rawKey方法

byte[] rawKey(Object key) {

        Assert.notNull(key, "non null key required");
//繼續(xù)跟keySerializer()
        if (keySerializer() == null && key instanceof byte[]) {
            return (byte[]) key;
        }

        return keySerializer().serialize(key);
}

恭喜找到源頭了,這里獲取的key的序列化對象。

RedisSerializer keySerializer() {
        return template.getKeySerializer();
}

推理中,StringRedisTempate可以獲取到值,來看一下這里面的一部分代碼,看看是否有可參考性

public StringRedisTemplate() {
        setKeySerializer(RedisSerializer.string());
        setValueSerializer(RedisSerializer.string());
        setHashKeySerializer(RedisSerializer.string());
        setHashValueSerializer(RedisSerializer.string());
}

同理找到RedisTemplate中類似的這段代碼

@Override
    public void afterPropertiesSet() {

        super.afterPropertiesSet();

        boolean defaultUsed = false;

        if (defaultSerializer == null) {

            defaultSerializer = new JdkSerializationRedisSerializer(
                    classLoader != null ? classLoader : this.getClass().getClassLoader());
        }

        if (enableDefaultSerializer) {

            if (keySerializer == null) {
                keySerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (valueSerializer == null) {
                valueSerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (hashKeySerializer == null) {
                hashKeySerializer = defaultSerializer;
                defaultUsed = true;
            }
            if (hashValueSerializer == null) {
                hashValueSerializer = defaultSerializer;
                defaultUsed = true;
            }
        }

        if (enableDefaultSerializer && defaultUsed) {
            Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
        }

        if (scriptExecutor == null) {
            this.scriptExecutor = new DefaultScriptExecutor<>(this);
        }

        initialized = true;
    }

或者可以根據(jù)斷點(diǎn)看到默認(rèn)的Serializer是JdkSerializationRedisSerializer,與StringRedisTemplate中不一致。


image.png

解決:在自定義的RedisConfig中,參考StringRedisTemplate,將對應(yīng)的幾個序列化方法加入。

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(RedisSerializer.string());
        template.setValueSerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        template.setHashValueSerializer(RedisSerializer.string());
        return template;
    }

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容