首先介绍一篇文章, 【问底】静行:FastJSON实现详解 http://www.csdn.net/article/2014-09-25/2821866
这篇文章讲到FastJSON通过createJavaBeanSerializer()创建的序列化类。通过该方法会获取两种序列化类,一种是直接的JavaBeanSerializer(根据类的get方法、public filed等JavaBean特征序列化),另一种是createASMSerializer(通过ASM框架生成的序列化字节码),优先使用第二种。
---------------------------------------------
看了FastJSON实现后,发现这种序列化方式和ProtoBuf很类似。在序列化类的基础上进行封装,就没有那么多的反射了(反射挺消耗时间的)
我们这里来分析下: 首先将类ASMSerializerFactory中方法createJavaBeanSerializer的IOUtils.write注释代码取消。修改下输出路径。
// org.apache.commons.io.IOUtils.write(code, new java.io.FileOutputStream( "/Users/jiaojianfeng/Documents/empleyment/tmp/fastjson/" + className + ".class"));
我们将生成的Serialize0.class反编译后得到:
import com.alibaba.fastjson.serializer.FilterUtils;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.JavaBeanSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerialContext;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.ASMUtils;
import com.jjf.Person;
import java.io.IOException;
import java.lang.reflect.Type;
public class Serialize0 implements ObjectSerializer {
private JavaBeanSerializer nature;
public Type name_asm_fieldPrefix;
public Type name_asm_fieldType = ASMUtils.getMethodType(Person.class,
"getName");
public Type age_asm_fieldPrefix;
public Type age_asm_fieldType = ASMUtils.getMethodType(Person.class,
"getAge");
public void write(JSONSerializer paramJSONSerializer, Object paramObject1,
Object paramObject2, Type paramType) throws IOException {
SerializeWriter localSerializeWriter = paramJSONSerializer.getWriter();
if (localSerializeWriter.isEnabled(SerializerFeature.SortField)) {
write1(paramJSONSerializer, paramObject1, paramObject2, paramType);
return;
}
Person localPerson = (Person) paramObject1;
if (localSerializeWriter.isEnabled(SerializerFeature.PrettyFormat)) {
if (this.nature == null)
this.nature = new JavaBeanSerializer(Person.class);
this.nature.write(paramJSONSerializer, paramObject1, paramObject2,
paramType);
return;
}
if (paramJSONSerializer.containsReference(paramObject1)) {
if (this.nature == null)
this.nature = new JavaBeanSerializer(Person.class);
this.nature.writeReference(paramJSONSerializer, paramObject1);
return;
}
if (paramJSONSerializer.isWriteAsArray(paramObject1, paramType)) {
writeAsArray(paramJSONSerializer, paramObject1, paramObject2,
paramType);
return;
}
SerialContext localSerialContext = paramJSONSerializer.getContext();
paramJSONSerializer.setContext(localSerialContext, paramObject1,
paramObject2);
localSerializeWriter.write("{\"@type\":\"com.jjf.Person\"");
char c = (paramJSONSerializer.isWriteClassName(paramType, paramObject1))
&& (paramType != paramObject1.getClass()) ? ',' : '{';
c = FilterUtils.writeBefore(paramJSONSerializer, paramObject1, c);
String str1 = "name";
Object localObject1;
Object localObject2;
if (FilterUtils.applyName(paramJSONSerializer, paramObject1, str1)) {
String str2 = localPerson.getName();
if (FilterUtils
.apply(paramJSONSerializer, paramObject1, str1, str2)) {
str1 = FilterUtils.processKey(paramJSONSerializer,
paramObject1, str1, str2);
localObject1 = str2;
localObject2 = FilterUtils.processValue(paramJSONSerializer,
paramObject1, str1, localObject1);
if (localObject1 != localObject2) {
if (localObject2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNullString(c, str1);
c = ',';
}
} else {
localSerializeWriter.write(c);
localSerializeWriter.writeFieldName(str1);
paramJSONSerializer.writeWithFieldName(localObject2,
str1, this.name_asm_fieldType);
c = ',';
}
} else if (str2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNullString(c, str1);
c = ',';
}
} else {
localSerializeWriter.writeFieldValue(c, str1, str2);
c = ',';
}
}
}
str1 = "age";
if (FilterUtils.applyName(paramJSONSerializer, paramObject1, str1)) {
int i = localPerson.getAge();
if (FilterUtils.apply(paramJSONSerializer, paramObject1, str1, i)) {
str1 = FilterUtils.processKey(paramJSONSerializer,
paramObject1, str1, i);
localObject1 = Integer.valueOf(i);
localObject2 = FilterUtils.processValue(paramJSONSerializer,
paramObject1, str1, localObject1);
if (localObject1 != localObject2) {
if (localObject2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNull(c, str1);
c = ',';
}
} else {
localSerializeWriter.write(c);
localSerializeWriter.writeFieldName(str1);
paramJSONSerializer.writeWithFieldName(localObject2,
str1);
c = ',';
}
} else {
localSerializeWriter.writeFieldValue(c, str1, i);
c = ',';
}
}
}
c = FilterUtils.writeAfter(paramJSONSerializer, paramObject1, c);
if (c == '{')
localSerializeWriter.write('{');
localSerializeWriter.write('}');
paramJSONSerializer.setContext(localSerialContext);
}
public void write1(JSONSerializer paramJSONSerializer, Object paramObject1,
Object paramObject2, Type paramType) throws IOException {
SerializeWriter localSerializeWriter = paramJSONSerializer.getWriter();
Person localPerson = (Person) paramObject1;
if (localSerializeWriter.isEnabled(SerializerFeature.PrettyFormat)) {
if (this.nature == null)
this.nature = new JavaBeanSerializer(Person.class);
this.nature.write(paramJSONSerializer, paramObject1, paramObject2,
paramType);
return;
}
if (paramJSONSerializer.containsReference(paramObject1)) {
if (this.nature == null)
this.nature = new JavaBeanSerializer(Person.class);
this.nature.writeReference(paramJSONSerializer, paramObject1);
return;
}
if (paramJSONSerializer.isWriteAsArray(paramObject1, paramType)) {
writeAsArray(paramJSONSerializer, paramObject1, paramObject2,
paramType);
return;
}
SerialContext localSerialContext = paramJSONSerializer.getContext();
paramJSONSerializer.setContext(localSerialContext, paramObject1,
paramObject2);
localSerializeWriter.write("{\"@type\":\"com.jjf.Person\"");
char c = (paramJSONSerializer.isWriteClassName(paramType, paramObject1))
&& (paramType != paramObject1.getClass()) ? ',' : '{';
c = FilterUtils.writeBefore(paramJSONSerializer, paramObject1, c);
String str1 = "age";
Object localObject1;
Object localObject2;
if (FilterUtils.applyName(paramJSONSerializer, paramObject1, str1)) {
int i = localPerson.getAge();
if (FilterUtils.apply(paramJSONSerializer, paramObject1, str1, i)) {
str1 = FilterUtils.processKey(paramJSONSerializer,
paramObject1, str1, i);
localObject1 = Integer.valueOf(i);
localObject2 = FilterUtils.processValue(paramJSONSerializer,
paramObject1, str1, localObject1);
if (localObject1 != localObject2) {
if (localObject2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNull(c, str1);
c = ',';
}
} else {
localSerializeWriter.write(c);
localSerializeWriter.writeFieldName(str1);
paramJSONSerializer.writeWithFieldName(localObject2,
str1);
c = ',';
}
} else {
localSerializeWriter.writeFieldValue(c, str1, i);
c = ',';
}
}
}
str1 = "name";
if (FilterUtils.applyName(paramJSONSerializer, paramObject1, str1)) {
String str2 = localPerson.getName();
if (FilterUtils
.apply(paramJSONSerializer, paramObject1, str1, str2)) {
str1 = FilterUtils.processKey(paramJSONSerializer,
paramObject1, str1, str2);
localObject1 = str2;
localObject2 = FilterUtils.processValue(paramJSONSerializer,
paramObject1, str1, localObject1);
if (localObject1 != localObject2) {
if (localObject2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNullString(c, str1);
c = ',';
}
} else {
localSerializeWriter.write(c);
localSerializeWriter.writeFieldName(str1);
paramJSONSerializer.writeWithFieldName(localObject2,
str1, this.name_asm_fieldType);
c = ',';
}
} else if (str2 == null) {
if (localSerializeWriter
.isEnabled(SerializerFeature.WriteMapNullValue)) {
localSerializeWriter.writeFieldNullString(c, str1);
c = ',';
}
} else {
localSerializeWriter.writeFieldValue(c, str1, str2);
c = ',';
}
}
}
c = FilterUtils.writeAfter(paramJSONSerializer, paramObject1, c);
if (c == '{')
localSerializeWriter.write('{');
localSerializeWriter.write('}');
paramJSONSerializer.setContext(localSerialContext);
}
public void writeAsArray(JSONSerializer paramJSONSerializer,
Object paramObject1, Object paramObject2, Type paramType)
throws IOException {
SerializeWriter localSerializeWriter = paramJSONSerializer.getWriter();
Person localPerson = (Person) paramObject1;
localSerializeWriter.write('[');
String str = "age";
localSerializeWriter.writeIntAndChar(localPerson.getAge(), ',');
str = "name";
localSerializeWriter.writeString(localPerson.getName(), ']');
}
}
序列化时调用的就是write方法。读者可以将源码修改下,让其调用类Serialize0的write方法,方便调试,查看处理过程。
当然,FastJSON中还有很多优化方案,像工具类SerializeWriter、IdentityHashMap、sort field、sort field fast match 等等。可自行通过源码学习。