【问题标题】:redisTemplate vs stringRedisTemplate! why redisTemplate set-command does not work?redisTemplate 与 stringRedisTemplate!为什么 redisTemplate 设置命令不起作用?
【发布时间】:2021-05-12 11:52:11
【问题描述】:

最近一直在用spring-boot-starter-data-redis;

我用的是spring-boot-version:2.3.8.RELEASE;

application.yml

spring:
  redis:
    cluster:
      nodes:
        - 10.253.48.212:6379
        - 10.253.48.212:6380
        - 10.253.48.213:6379
        - 10.253.48.213:6380
        - 10.253.48.214:6379
        - 10.253.48.214:6380

我按照文章设置了Redis-Cluster; https://redis.io/topics/cluster-tutorial

设置过程也记录在additor;虽然注释是中文的;

我按照spring-data-redis的文章使用Redis-Client;

我根据 [10.6.通过 RedisTemplate 处理对象];

但是redisTemplate和stringRedisTemplate有问题;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RedisApp.class})
public class RedisTest {

    @Resource(name="stringRedisTemplate")
    private ValueOperations<String, String> stringValueOperations;

    @Resource(name="redisTemplate")
    private ValueOperations<String, String> valueOperations;

    @Test
    public void test() {
        stringValueOperations.set("name", "yufr-bigName");
        valueOperations.set("name", "yufr");
        System.out.println(stringValueOperations.get("name"));
        System.out.println(valueOperations.get("name"));
    }

}

导致idea-console:

yufr-bigName
yufr

导致 redis-cluster-server:

10.253.48.214:6379> get name
"yufr-bigName"

为什么 redisTemplate 设置命令不起作用?

【问题讨论】:

    标签: spring-data-redis


    【解决方案1】:

    RedisSerializer 将键“名称”序列化为其他键,因此 redisTemplate 似乎不起作用;

    关键代码是RedisSerializer;

        byte[] rawKey(Object key) {
    
            Assert.notNull(key, "non null key required");
    
            if (keySerializer() == null && key instanceof byte[]) {
                return (byte[]) key;
            }
    
            return keySerializer().serialize(key);
        }
    
        byte[] rawValue(Object value) {
    
            if (valueSerializer() == null && value instanceof byte[]) {
                return (byte[]) value;
            }
    
            return valueSerializer().serialize(value);
        }
    

    defaultSerializer 是 JdkSerializationRedisSerializer

    class RedisTemplate ... {
    
        ...
    
        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;
                }
    
                ...
    
            }
        }
    }
    

    最终的序列化器是 org.springframework.core.serializer.DefaultSerializer

        public void serialize(Object object, OutputStream outputStream) throws IOException {
            if (!(object instanceof Serializable)) {
                throw new IllegalArgumentException(getClass().getSimpleName() + " requires a Serializable payload " +
                        "but received an object of type [" + object.getClass().getName() + "]");
            }
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
        }
    

    所以字符串键“name”将被objectOutputStream处理;

        @Test
        public void serialize() {
            ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
            try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(out)) {
                objectOutputStream.writeObject("name");
                objectOutputStream.flush();
            } catch (IOException ioException) {
                
            }
            
            // �� t name
            System.out.println(new String(out.toByteArray()));
        }
    

    这样 valueOperations.set("name", "yufr");不工作!

    【讨论】:

      猜你喜欢
      • 2016-11-24
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2018-11-24
      相关资源
      最近更新 更多