Hessian源码学习(五)
紧接着上一篇,我们来看看另一个序列化类JavaSerializer。
这个类一般是用来序列化我们自定义类的,所以更多的时候我们用到的是它,今天打算分析两个方面,第一是JavaSerializer本身实现,第二分析下反序列化的时候为什么会存在父类同名field值覆盖子类field问题
1.JavaSerializer实现
// 首先看一下JavaSerializer的构造方法public JavaSerializer(Class cl, ClassLoader loader){...// 存放简单类型字段 ArrayList primitiveFields = new ArrayList();// 存放复杂类型字段 ArrayList compoundFields = new ArrayList(); // 获取子类到父类所有field字段 for (; cl != null; cl = cl.getSuperclass()) { Field []fields = cl.getDeclaredFields(); for (int i = 0; i < fields.length; i++) {Field field = fields[i];// 过滤掉这两种类型的fieldif (Modifier.isTransient(field.getModifiers())|| Modifier.isStatic(field.getModifiers())) continue;field.setAccessible(true);// 按类型存入arrayListif (field.getType().isPrimitive()|| (field.getType().getName().startsWith("java.lang.")&& ! field.getType().equals(Object.class))) primitiveFields.add(field);else compoundFields.add(field); }}// 合并成一个list并转换成数组 (ps: 这样看来之前用两个list来存放似乎没有什么意义?!) ArrayList fields = new ArrayList(); fields.addAll(primitiveFields); fields.addAll(compoundFields); _fields = new Field[fields.size()]; fields.toArray(_fields); _fieldSerializers = new FieldSerializer[_fields.length];// 获取每一个field对应的FieldSerializer(注1) for (int i = 0; i < _fields.length; i++) { _fieldSerializers[i] = getFieldSerializer(_fields[i].getType()); }}
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException{ ... Class cl = obj.getClass(); ...// 写类头,输出格式: 'Mt'[类名长度][类名] int ref = out.writeObjectBegin(cl.getName());// 对于HessianOutput 总是返回-2 if (ref < -1) { writeObject10(obj, out); } else { if (ref == -1) {writeDefinition20(out);out.writeObjectBegin(cl.getName()); } writeInstance(obj, out); }}private void writeObject10(Object obj, AbstractHessianOutput out) throws IOException{// 循环序列化该类的field(先子类后父类) for (int i = 0; i < _fields.length; i++) { Field field = _fields[i]; // 序列化field名 out.writeString(field.getName()); // 序列化field值 _fieldSerializers[i].serialize(out, obj, field); } // 结束标记 'z' out.writeMapEnd();}
for (int i = 0; i < _fields.length; i++) { _fieldSerializers[i] = getFieldSerializer(_fields[i].getType());}
private static FieldSerializer getFieldSerializer(Class type){// 对于简单类型的处理 if (int.class.equals(type) || byte.class.equals(type) || short.class.equals(type) || int.class.equals(type)) { return IntFieldSerializer.SER; } else if (long.class.equals(type)) { return LongFieldSerializer.SER; } else if (double.class.equals(type) || float.class.equals(type)) { return DoubleFieldSerializer.SER; } else if (boolean.class.equals(type)) { return BooleanFieldSerializer.SER; } else if (String.class.equals(type)) { return StringFieldSerializer.SER; } else if (java.util.Date.class.equals(type) || java.sql.Date.class.equals(type) || java.sql.Timestamp.class.equals(type) || java.sql.Time.class.equals(type)) { return DateFieldSerializer.SER; }// 对于复杂类型的处理 else // 所有其他类型field(比如自定义类) 就使用默认FieldSerializer return FieldSerializer.SER;}
static class BooleanFieldSerializer extends FieldSerializer { static final FieldSerializer SER = new BooleanFieldSerializer(); void serialize(AbstractHessianOutput out, Object obj, Field field) throws IOException { boolean value = false; try {value = field.getBoolean(obj); } catch (IllegalAccessException e) {log.log(Level.FINE, e.toString(), e); } out.writeBoolean(value); }}static class IntFieldSerializer extends FieldSerializer { static final FieldSerializer SER = new IntFieldSerializer(); void serialize(AbstractHessianOutput out, Object obj, Field field) throws IOException { int value = 0; try {value = field.getInt(obj); } catch (IllegalAccessException e) {log.log(Level.FINE, e.toString(), e); } out.writeInt(value); }}static class FieldSerializer { static final FieldSerializer SER = new FieldSerializer(); void serialize(AbstractHessianOutput out, Object obj, Field field) throws IOException { Object value = null; try {value = field.get(obj); } catch (IllegalAccessException e) {log.log(Level.FINE, e.toString(), e); } try {out.writeObject(value); // 这里是怎么做的? 是不是又回到了前面? ^_^(不清楚可以看Hessian源码学习(三)) } catch (RuntimeException e) {throw new RuntimeException(e.getMessage() + "\n Java field: " + field, e); } catch (IOException e) {throw new IOExceptionWrapper(e.getMessage() + "\n Java field: " + field, e); } }}
public JavaDeserializer(Class cl){ ...// 最关键的一段代码 _fieldMap = getFieldMap(cl);...}我们看下getFieldMap(cl)的实现:protected HashMap getFieldMap(Class cl) {// 创建一个hashmap存放field (有没有觉得和JavaSerializer不一致,JavaSerializer是把field存放到一个list中去) HashMap fieldMap = new HashMap(); // 循环读取从子类到父类的field for (; cl != null; cl = cl.getSuperclass()) { Field []fields = cl.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) continue;// 重点!!!! 由于是从子类循环到父类,所以若是存在同名字段,fieldMap中放的都是子类字段!!!! else if (fieldMap.get(field.getName()) != null) continue; try { field.setAccessible(true); } catch (Throwable e) { e.printStackTrace(); }Class type = field.getType();FieldDeserializer deser;if (String.class.equals(type)) deser = new StringFieldDeserializer(field);else if (byte.class.equals(type)) { deser = new ByteFieldDeserializer(field);}else if (short.class.equals(type)) { // 省略}else { deser = new ObjectFieldDeserializer(field);} fieldMap.put(field.getName(), deser); } } return fieldMap; }