dubbo反序列化为何类 全类型名称不一样会转成map

在使用dubbo消费者调用服务端的服务时,一旦返回体接收到的类目消费者服务中心找不到会被转成map但是这是为什么呢?

我们来看看dubbo2.7.x源码,

看到

Hessian2Input类的readObject(Class expectedClass, Class<?>... expectedTypes)的方法

如果返回的是一个类则会走到

            case 'C': {
                readObjectDefinition(expectedClass);

                return readObject(expectedClass);
            }
readObjectDefinition会将类的全路径名称和类的属性字段进行保存,和我们的目的无关,忽略
    public Object readObject(Class cl)
            throws IOException {
        return readObject(cl, null, null);
    }

public Object readObject(Class expectedClass, Class<?>... expectedTypes) throws IOException {

            ... //省略
            case 0x6f: {
                int ref = tag - 0x60;
                int size = _classDefs.size();

                if (ref < 0 || size <= ref)
                    throw new HessianProtocolException("'" + ref + "' is an unknown class definition");

                ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref);

                return readObjectInstance(expectedClass, def);
            }
}

紧接着会调用readObjectInstance(Class cl, ObjectDefinition def)

    private Object readObjectInstance(Class cl, ObjectDefinition def)
            throws IOException {
        String type = def.getType();
        String[] fieldNames = def.getFieldNames();

        if (cl != null) {
            Deserializer reader;
            reader = findSerializerFactory().getObjectDeserializer(type, cl);

            return reader.readObject(this, fieldNames);
        } else {
            return findSerializerFactory().readObject(this, type, fieldNames);
        }
    }

核心代码就是reader = findSerializerFactory().getObjectDeserializer(type, cl);

public Deserializer getObjectDeserializer(String type, Class cl)
        throws HessianProtocolException {
    Deserializer reader = getObjectDeserializer(type);
    ...

}

    public Deserializer getObjectDeserializer(String type)
            throws HessianProtocolException {
        //获取序列化类
        Deserializer deserializer = getDeserializer(type);

        //如果deserializer 返回null, 会返回new MapDeserializer(HashMap.class)序列化器
        if (deserializer != null)
            return deserializer;
        else if (_hashMapDeserializer != null)
            return _hashMapDeserializer;
        else {
            _hashMapDeserializer = new MapDeserializer(HashMap.class);

            return _hashMapDeserializer;
        }
    }

public Deserializer getDeserializer(String type)
            throws HessianProtocolException {
        if (type == null || type.equals("") || _typeNotFoundDeserializerMap.containsKey(type))
            return null;

        Deserializer deserializer;

        if (_cachedTypeDeserializerMap != null) {
            deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);

            if (deserializer != null)
                return deserializer;
        }


        deserializer = (Deserializer) _staticTypeMap.get(type);
        if (deserializer != null)
            return deserializer;

        if (type.startsWith("[")) {
            Deserializer subDeserializer = getDeserializer(type.substring(1));

            if (subDeserializer != null)
                deserializer = new ArrayDeserializer(subDeserializer.getType());
            else
                deserializer = new ArrayDeserializer(Object.class);
        //如果不是数组 且不在不识别类缓存map中,会走这里
        } else if (_unrecognizedTypeCache.get(type) == null) {
            try {
                //如果消费端类不存在就会抛出异常, deserializer 即为 null
                Class cl = Class.forName(type, false, _loader);
                deserializer = getDeserializer(cl);
            } catch (Exception e) {
                log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + _loader + ":\n" + e);
                _typeNotFoundDeserializerMap.put(type, PRESENT);
                log.log(Level.FINER, e.toString(), e);
                _unrecognizedTypeCache.put(type, new AtomicLong(1L));
            }
        } else {
            ((AtomicLong) _unrecognizedTypeCache.get(type)).incrementAndGet();
            if (((AtomicLong) _unrecognizedTypeCache.get(type)).get() % 2000L == 0L)
                ((AtomicLong) _unrecognizedTypeCache.get(type)).getAndSet(1L);
        }

        if (deserializer != null) {
            if (_cachedTypeDeserializerMap == null)
                _cachedTypeDeserializerMap = new ConcurrentHashMap(8);

            _cachedTypeDeserializerMap.put(type, deserializer);
        }

        return deserializer;
    }

可以看到获取到的序列化器为new MapDeserializer(HashMap.class)

而这个序列化器的序列化方式,就是将字段放到map中

    public Object readObject(AbstractHessianInput in,
                             String[] fieldNames)
            throws IOException {
        Map map = createMap();

        int ref = in.addRef(map);

        for (int i = 0; i < fieldNames.length; i++) {
            String name = fieldNames[i];

            map.put(name, in.readObject());
        }

        return map;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李文区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值