139 lines
4.2 KiB
Markdown
139 lines
4.2 KiB
Markdown
# 反序列化CodeGen算法介绍
|
||
fastjson2会使用codegen来优化反序列化的性能,用到的codegen技术包括:
|
||
* ASM 基于内置asm 9.2裁剪版实现的动态字节码生成类
|
||
* Annotation Process Tools(APT)
|
||
|
||
## 1. 实现算法介绍
|
||
|
||

|
||
|
||
上图中算法1是常规实现;算法2是fastjson2的实现(最初是dsljson引入,被fastjson借鉴);算法3是新引入的实现
|
||
|
||
我们要将json反序列化为如下的Image类
|
||
```java
|
||
@Data
|
||
public class Image {
|
||
private int height;
|
||
private Size size;
|
||
private String title;
|
||
private String uri;
|
||
private int width;
|
||
}
|
||
```
|
||
|
||
生成如下的代码来快速将json中的name和字段关联起来:
|
||
```java
|
||
public final class Image_FASTJSONReader
|
||
extends com.alibaba.fastjson2.reader.ObjectReader5 {
|
||
|
||
public Object readObject(
|
||
com.alibaba.fastjson2.JSONReader jsonReader,
|
||
java.lang.reflect.Type fieldType,
|
||
Object fieldName,
|
||
long features
|
||
) {
|
||
Image object = new Image();
|
||
|
||
while (!jsonReader.nextIfObjectEnd()) {
|
||
switch (jsonReader.getRawInt()) {
|
||
// '"' | ('w' << 8) | ('i' << 16) | ('d' << 24) == 1684633378
|
||
// 't' | ('h' << 8) | ('"' << 16) | (':' << 24) == 975333492
|
||
case 1684633378: // "wid
|
||
if (jsonReader.nextIfName4Match5(975333492)) { // th":
|
||
object.setWidth(
|
||
jsonReader.readInt32Value()
|
||
);
|
||
continue;
|
||
}
|
||
break;
|
||
// '"' | ('h' << 8) | ('e' << 16) | ('i' << 24) == 1768253474
|
||
// 'g' | ('h' << 8) | ('t' << 16) | ('"' << 24) == 578054247
|
||
case 1768253474: // "hei
|
||
if (jsonReader.nextIfName4Match6(578054247)) { // ght"
|
||
object.setHeight(
|
||
jsonReader.readInt32Value()
|
||
);
|
||
continue;
|
||
}
|
||
break;
|
||
// '"' | ('u' << 8) | ('r' << 16) | ('i' << 24) == 1769108770
|
||
case 1769108770: // "uri"
|
||
if (jsonReader.nextIfName4Match3()) {
|
||
object.setUri(
|
||
jsonReader.readString()
|
||
);
|
||
continue;
|
||
}
|
||
break;
|
||
// ...
|
||
default:
|
||
break;
|
||
}
|
||
// ....
|
||
}
|
||
return object;
|
||
}
|
||
}
|
||
```
|
||
|
||
相关方法在JSONReader中的实现
|
||
```java
|
||
class JSONReaderUTF8 implements JSONReader {
|
||
public final int getRawInt() {
|
||
if (offset + 3 < bytes.length) {
|
||
return UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 1);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
public boolean nextIfName4Match3() {
|
||
offset += 5;
|
||
|
||
if (bytes[offset - 2] != '"' || bytes[offset - 1] != ':') {
|
||
return false;
|
||
}
|
||
|
||
// ...
|
||
|
||
return true;
|
||
}
|
||
|
||
public final boolean nextIfName4Match4(byte c4) {
|
||
offset += 6;
|
||
if (bytes[offset - 3] != c4 || bytes[offset - 2] != '"' || bytes[offset - 1] != ':') {
|
||
return false;
|
||
}
|
||
// ...
|
||
return true;
|
||
}
|
||
|
||
public boolean nextIfName4Match5(int name1) {
|
||
offset += 7;
|
||
if (UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 4) != name1) {
|
||
return false;
|
||
}
|
||
// ...
|
||
return true;
|
||
}
|
||
|
||
public boolean nextIfName4Match6(int name1) {
|
||
offset += 8;
|
||
if (UNSAFE.getInt(bytes, ARRAY_BYTE_BASE_OFFSET + offset - 5) != name1 || bytes[offset - 1] != ':') {
|
||
return false;
|
||
}
|
||
// ...
|
||
return true;
|
||
}
|
||
}
|
||
```
|
||
|
||
这样的实现好处是,不需要将key读取出来,也不需要将使用JSONReader#readFieldNameHashCode,通过key的前缀3个字符读取一个int值,使用switch来路由到相应字段的处理。
|
||
|
||
## 2. 算法实现代码
|
||
生成代码的实现:
|
||
* ASM实现 com.alibaba.fastjson2.reader.ObjectReaderCreatorASM#genRead243
|
||
* APT实现 com.alibaba.fastjson2.internal.processor.JSONCompiledAnnotationProcessor.genRead243
|
||
|
||
|
||
|