前言
上文ASM入门篇中除了对ASM
的使用做了介绍,同时也提到ASM
被使用的一些场景,其中有一项就是ASM
被用来代替Java
反射;FastJson
作为序列化工具,就使用了ASM
来代替反射的使用,提高整体的性能。
序列化
序列化就是将对象转换成Json
格式的字符串,然后用来持久化或者网络传输;FastJson
提供了接口类ObjectSerializer
:
public interface ObjectSerializer {
void write(JSONSerializer serializer, //
Object object, //
Object fieldName, //
Type fieldType, //
int features) throws IOException;
}
- serializer:序列化上下文;
- object:需要转换为Json的对象;
- fieldName:父对象字段名称;
- fieldType:父对象字段类型;
- features:父对象字段序列化features;
ObjectSerializer
的实现类有多种,最常见就是序列化JavaBean
的JavaBeanSerializer
,当然还有一些其他类型的序列化工具类比如:基本类型、日期类型、枚举类型、一些特殊类型等等;引入的ASM正是对JavaBeanSerializer
的优化,当然要使用ASM优化也是有条件的,满足条件的情况下会通过ASM生成JavaBeanSerializer
的子类,代替里面的反射操作;
启用条件
FastJson提供了ASM的开关,默认开启状态,同时在满足一定的条件下才能使用ASMSerializerFactory
创建ASMSerializer
;
开关
SerializeConfig
中提供了asm开关标识:
private boolean asm = !ASMUtils.IS_ANDROID
默认安卓环境下为false
,否则为true
,所有服务端开发一般都是开启asm的;
JSONType注解
- 如果配置了
serializer
,则使用配置的序列化类:
@JSONType(serializer = JavaBeanSerializer.class)
- 如果配置了
asm
为false
,则不启用asm
:
@JSONType(asm = false)
- 如果配置了指定几种
SerializerFeature
,则不开启asm
:
@JSONType(serialzeFeatures = {
SerializerFeature.WriteNonStringValueAsString,SerializerFeature.WriteEnumUsingToString,SerializerFeature.NotWriteDefaultValue,SerializerFeature.BrowserCompatible})
- 如果配置了
SerializeFilter
,则不开启asm
:
@JSONType(serialzeFilters = {
})
BeanType类信息
如果类修饰符不为public
,则不开启asm
,直接使用JavaBeanSerializer
;
如果类名称字符中包含了<001 || >177 || ==.
的字符,则不启用asm
;
如果类是接口类则不启用asm
;
对类属性的检查,包括类型,返回值,注解等,不符合的情况下同样不启用asm
;
创建ASMSerializer
通过ASM
为每个JavaBean
生成一个独立的JavaBeanSerializer
子类,具体步骤如下:
生成类名
创建类之前需要生成一个唯一的名称:
String className = "ASMSerializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName()
这里的seed
是一个AtomicLong
变量;以Person
为例,则生成的className
为ASMSerializer_1_Person
;
生成子类
通过ASM的ClassWriter
来生成JavaBeanSerializer
的子类,重写write
方法,JavaBeanSerializer
中的write
方法会使用反射从JavaBean
中获取相关信息,而通过ASM生成的ASMSerializer_1_Person
,是针对Person
独有的序列化工具类,可以看部分代码:
public class ASMSerializer_1_Person
extends JavaBeanSerializer
implements ObjectSerializer {
public ASMSerializer_1_Person(SerializeBeanInfo serializeBeanInfo) {
super(serializeBeanInfo);
}
public void write(JSONSerializer jSONSerializer, Object object, Object object2, Type type, int n) throws IOException {
if (object == null) {
jSONSerializer.writeNull();
return;
}
SerializeWriter serializeWriter = jSONSerializer.out;
if (!this.writeDirect(jSONSerializer)) {
this.writeNormal(jSONSerializer, object, object2, type, n);
return;
}
if (serializeWriter.isEnabled(32768)) {
this.writeDirectNonContext(jSONSerializer, object, object2, type, n);
return;
}
Person person = (Person)object;
if (this.writeReference(jSONSerializer, object, n)) {
return;
}
if (serializeWriter.isEnabled(0x200000)) {
this.writeAsArray(jSONSerializer, object, object2, type, n);
return