2021SC@SDUSC
上一篇我们分析了ParserConfig的使用方法、关键变量的含义以及checkAutoType方法ConfigFromPropety方法的解析,这篇文章我们继续分析ParserConfig的另外几个关键方法,深度了解它的作用原理。
getDeserializer(Type type)
该方法用于获取指定类型的反序列化器。反序列化匹配getDeserializer(Type)主要特定处理了泛型类型,取出泛型类型真实类型还是委托内部ParserConfig#getDeserializer(java.lang.Class<?>, java.lang.reflect.Type)进行精确类型查找。
先上代码:
public ObjectDeserializer getDeserializer(Type type) {
ObjectDeserializer deserializer = get(type);
if (deserializer != null) {
return deserializer;
}
if (type instanceof Class<?>) {
return getDeserializer((Class<?>) type, type);
}
if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class<?>) {
return getDeserializer((Class<?>) rawType, type);
} else {
return getDeserializer(rawType);
}
}
if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
Type[] upperBounds = wildcardType.getUpperBounds();
if (upperBounds.length == 1) {
Type upperBoundType = upperBounds[0];
return getDeserializer(upperBoundType);
}
}
return JavaObjectDeserializer.instance;
}
可以看到该方法的执行流程是:
- 首先从内部已经注册查找特定class的反序列化实例
- 如果是引用类型,根据特定类型再次匹配
- 获取泛型类型原始类型
- 如果泛型原始类型是引用类型,根据特定类型再次匹配
- 递归调用反序列化查找
- 如果类型是通配符或者限定类型,获取泛型上界,根据特定类型再次匹配
- 如果无法匹配到,使用默认JavaObjectDeserializer反序列化
createJavaBeanDeserializer
该方法用于创建特定javabean的反序列化器,先看看代码:
public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable & !this.fieldBased;
if (asmEnable) {
JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
if (jsonType != null) {
Class<?> deserializerClass = jsonType.deserializer();
if (deserializerClass != Void.class) {
try {
Object deseralizer = deserializerClass.newInstance();
if (deseralizer instanceof ObjectDeserializer) {
return (ObjectDeserializer) deseralizer;
}
} catch (Throwable e) {
// skip
}
}
asmEnable = jsonType.asm()
&& jsonType.parseFeatures().length == 0;
}
if (asmEnable) {
Class<?> superClass = JavaBeanInfo.getBuilderClass(clazz, jsonType);
if (superClass == null) {
superClass = clazz;
}
for (;;) {
if (!Modifier.isPublic(superClass.getModifiers())) {
asmEnable = false;
break;
}
superClass = superClass.getSuperclass();
if (superClass == Object.class || superClass == null) {
break;
}
}
}
}
if (clazz.getTypeParameters().length != 0) {
asmEnable = false;
}
if (asmEnable && asmFactory != null && asmFactory.classLoader.isExternalClass(clazz)) {
asmEnable = false;
}
if (asmEnable) {
asmEnable = ASMUtils.checkName(clazz.getSimpleName());
}
if (asmEnable) {
if (clazz.isInterface()) {
asmEnable = false;
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz
, type
, propertyNamingStrategy
,false
, TypeUtils.compatibleWithJavaBean
, jacksonCompatible
);
if (asmEnable && beanInfo.fields.length > 200) {
asmEnable = false;
}
Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
if (asmEnable && defaultConstructor == null && !clazz.isInterface()) {
asmEnable = false;
}
for (FieldInfo fieldInfo : beanInfo.fields) {
if (fieldInfo.getOnly) {
asmEnable = false;
break;
}
Class<?> fieldClass = fieldInfo.fieldClass;
if (!Modifier.isPublic(fieldClass.getModifiers())) {
asmEnable = false;
break;
}
if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
asmEnable = false;
break;
}
if (fieldInfo.getMember() != null //
&& !ASMUtils.checkName(fieldInfo.getMember().getName())) {
asmEnable = false;
break;
}
JSONField annotation = fieldInfo.getAnnotation();
if (annotation != null //
&& ((!ASMUtils.checkName(annotation.name())) //
|| annotation.format().length() != 0 //
|| annotation.deserializeUsing() != Void.class //
|| annotation.parseFeatures().length != 0 //
|| annotation.unwrapped())
|| (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) {
asmEnable = false;
break;
}
if (fieldClass.isEnum()) { // EnumDeserializer
ObjectDeserializer fieldDeser = this.getDeserializer(fieldClass);
if (!(fieldDeser instanceof EnumDeserializer)) {
asmEnable = false;
break;
}
}
}
}
if (asmEnable) {
if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
asmEnable = false;
}
}
if (asmEnable) {
if (TypeUtils.isXmlField(clazz)) {
asmEnable = false;
}
}
if (!asmEnable) {
return new JavaBeanDeserializer(this, clazz, type);
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy);
try {
return asmFactory.createJavaBeanDeserializer(this, beanInfo);
// } catch (VerifyError e) {
// e.printStackTrace();
// return new JavaBeanDeserializer(this, clazz, type);
} catch (NoSuchMethodException ex) {
return new JavaBeanDeserializer(this, clazz, type);
} catch (JSONException asmError) {
return new JavaBeanDeserializer(this, beanInfo);
} catch (Exception e) {
throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
}
}
代码比较长,其中包括许多if分支,总结下来,这个方法主要做了这些事:
先确定是否使用asm。首先对asmEnable判断,如果是true,则使用asm的方式生成特定javabean的反序列化器,否则,使用常规的set方法进行反序列化(效率低、不安全)。
在确定使用asm的前提下,先判断要反序列化的类型JSONType,如果默认的反序列化解析器库中存在相应的解析器,那么调用相应的解析器。如果没有,则生成对应的解析器:先确定json字符串有哪些属性,然后构造对应的setter、getter,使用前几篇提到的asm方法直接生成class文件。
initJavaBeanDeserializers
讲完了Java bean构造器如何动态生成,就可以看看在如何对其进行初始化了。
public void initJavaBeanDeserializers(Class<?>... classes) {
if (classes == null) {
return;
}
for (Class<?> type : classes) {
if (type == null) {
continue;
}
ObjectDeserializer deserializer = createJavaBeanDeserializer(type, type);
putDeserializer(type, deserializer);
}
}
首先对传入的class对象判断是否为空,如果为空,直接返回。不为空的话,一个一个对class对象判断其type,type若为空,跳过这一轮循环进入下一轮循环。不为空,则调用createJavaBeanDeserializer为其生成反序列化器,并将对应的type和反序列化器放入一个map容器中。
总结
这两篇着重分析了ParserConfig的关键方法的作用及其实现原理。ParserConfig的存在,使得Fastjson可以实现高度定制化,调用者可以自由地对Fastjson进行配置从而达到自己的目的。