所有序列化的API都在JSON类中,方法名称为toJSONString,或者我们也可以设计自己的序列化方法,代码如下:
public class MyJSON { public static String toJSONString(Object object, SerializeConfig config, SerializeFilter[] filters, SerializerFeature[] features) { SerializeWriter out = new SerializeWriter(); try { // SerializeConfig可以理解为一个Map<Type,ObjectSerializer>, // 内部保存着类型与对应的对象序列化器之间的映射关系 if (config == null) config = SerializeConfig.getGlobalInstance(); // 核心序列化器,主要负责调用SerializeConfig根据value选择合适的对象序列化器 // 内部还保存着输出流对象,以及各种过滤器 JSONSerializer serializer = new JSONSerializer(out, config); // 所有特性最终会合成为一个int值,保存在输出流对象中 if (features != null) for (SerializerFeature feature : features) { serializer.config(feature, true); } // 如上面所说,过滤器保存在核心序列化器中 if (filters != null && filters.length > 0) setFilter(serializer, filters); // 序列化过程的入口方法 serializer.write(object); return out.toString(); } finally { out.close(); } } private static void setFilter(JSONSerializer serializer, SerializeFilter... filters) { for (SerializeFilter filter : filters) { setFilter(serializer, filter); } } private static void setFilter(JSONSerializer serializer, SerializeFilter filter) { if (filter == null) { return; } if (filter instanceof PropertyPreFilter) { serializer.getPropertyPreFilters().add((PropertyPreFilter) filter); } if (filter instanceof NameFilter) { serializer.getNameFilters().add((NameFilter) filter); } if (filter instanceof ValueFilter) { serializer.getValueFilters().add((ValueFilter) filter); } if (filter instanceof PropertyFilter) { serializer.getPropertyFilters().add((PropertyFilter) filter); } if (filter instanceof BeforeFilter) { serializer.getBeforeFilters().add((BeforeFilter) filter); } if (filter instanceof AfterFilter) { serializer.getAfterFilters().add((AfterFilter) filter); } if (filter instanceof LabelFilter) { serializer.getLabelFilters().add((LabelFilter) filter); } } }
调用方法时需要传入一个要序列化的目标对象object,以及三个可选参数,分别为SerializeConfig、SerializeFilter[]、SerializerFeature[]。这三个参数之所以为可选,是因为它们均有默认配置。
SerializeConfig:序列化配置,我们可以把它理解为一个Map<Class,ObjectSerializer>,它的内部保存着所有被序列化对象的类型,与序列化此对象要使用的ObjectSerializer序列化器之间的映射关系。另外,如果遇到不存在的javaBean类型,它的内部还可以自动创建JavaBeanSerializer(包括直接创建JavaBeanSerializer对象,或者通过asm框架创建ASMJavaBeanSerializer的子类对象)。
SerializeFilter:序列化过滤器???
SerializerFeature:序列化器特性,主要用于控制序列化过程中的一些行为特性
序列化过程的入口其实就是serializer.write(object);方法的调用,具体执行过程如下:
public final void write(Object object) { // 如果value为null则直接输出"null"并返回 if (object == null) { out.writeNull(); return; } // 获取value对象的类型 Class<?> clazz = object.getClass(); // 根据Class类型,从SerializeConfig中选择合适的ObjectSerializer ObjectSerializer writer = getObjectWriter(clazz); try { // 调用ObjectSerializer序列化这个value // 因为输入的初始value对象没有与之对应的字段名称, // 因此第三(字段名称)和第四(字段类型)两个参数为null writer.write(this, object, null, null, 0); } catch (IOException e) { throw new JSONException(e.getMessage(), e); } }
这就是为什么我说JSONSerializer只负责调用SerializeConfig选择合适的ObjectSerializer进行序列化的原因。
因此,我们需要关注的重点有三个:
fastjson内部有多少种对象序列化器(即ObjectSerializer有多少个实现类)?
每种对象序列化器是如何工作的?
SerializeConfig中有多少种类型与对象序列化器之间的映射关系
ObjectSerializer接口类图如下:(点击可查看放大后的清晰图片)
整个体系共计61个实现类,以及一个子接口(AutowiredObjectSerializer)
具体每种对象序列化器如何工作,我会单开专题讲解,
在SerializeConfig的构造方法中,会添加许多默认支持的映射关系,每个新创建的SerializeConfig对象,都会支持这些类型的序列化。
put(Boolean.class, BooleanCodec.instance); put(Character.class, CharacterCodec.instance); put(Byte.class, IntegerCodec.instance); put(Short.class, IntegerCodec.instance); put(Integer.class, IntegerCodec.instance); put(Long.class, LongCodec.instance); put(Float.class, FloatCodec.instance); put(Double.class, DoubleSerializer.instance); put(BigDecimal.class, BigDecimalCodec.instance); put(BigInteger.class, BigIntegerCodec.instance); put(String.class, StringCodec.instance); put(byte[].class, ByteArraySerializer.instance); put(short[].class, ShortArraySerializer.instance); put(int[].class, IntArraySerializer.instance); put(long[].class, LongArraySerializer.instance); put(float[].class, FloatArraySerializer.instance); put(double[].class, DoubleArraySerializer.instance); put(boolean[].class, BooleanArraySerializer.instance); put(char[].class, CharArraySerializer.instance); put(Object[].class, ObjectArraySerializer.instance); put(Class.class, ClassSerializer.instance); put(SimpleDateFormat.class, DateFormatSerializer.instance); put(Locale.class, LocaleCodec.instance); put(Currency.class, CurrencyCodec.instance); put(TimeZone.class, TimeZoneCodec.instance); put(UUID.class, UUIDCodec.instance); put(InetAddress.class, InetAddressCodec.instance); put(Inet4Address.class, InetAddressCodec.instance); put(Inet6Address.class, InetAddressCodec.instance); put(InetSocketAddress.class, InetSocketAddressCodec.instance); put(File.class, FileCodec.instance); put(URI.class, URICodec.instance); put(URL.class, URLCodec.instance); put(Appendable.class, AppendableSerializer.instance); put(StringBuffer.class, AppendableSerializer.instance); put(StringBuilder.class, AppendableSerializer.instance); put(Pattern.class, PatternCodec.instance); put(Charset.class, CharsetCodec.instance); // atomic put(AtomicBoolean.class, AtomicBooleanSerializer.instance); put(AtomicInteger.class, AtomicIntegerSerializer.instance); put(AtomicLong.class, AtomicLongSerializer.instance); put(AtomicReference.class, ReferenceCodec.instance); put(AtomicIntegerArray.class, AtomicIntegerArrayCodec.instance); put(AtomicLongArray.class, AtomicLongArrayCodec.instance); put(WeakReference.class, ReferenceCodec.instance); put(SoftReference.class, ReferenceCodec.instance); // awt if (!awtError) { try { put(Class.forName("java.awt.Color"), ColorCodec.instance); put(Class.forName("java.awt.Font"), FontCodec.instance); put(Class.forName("java.awt.Point"), PointCodec.instance); put(Class.forName("java.awt.Rectangle"), RectangleCodec.instance); } catch (Throwable e) { awtError = true; // skip } } // jdk8 if (!jdk8Error) { try { put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); } catch (Throwable e) { // skip jdk8Error = true; } } if (!oracleJdbcError) { try { put(Class.forName("oracle.sql.DATE"), DateSerializer.instance); put(Class.forName("oracle.sql.TIMESTAMP"), DateSerializer.instance); } catch (Throwable e) { // skip oracleJdbcError = true; } }
因此,fastjson预定义的ObjectSerializer可识别的类型包括:
基本类型包装类:Boolean、Character、Byte、Short、Integer、Long、Float、Double
高精度数:BigDecimal、BigInteger
String
基本类型的数组:boolean[]、char[]、byte[]、short[]、int[]、long[]、float[]、double[]
Object[]、Class、SimpleDateFormat、Locale、Currency、TimeZone、UUID、InetAddress、Inet4Address、Inet6Address、InetSocketAddress、File、URI、URL、Appendable、StringBuffer、StringBuilder、Pattern、Charset
原子性对象:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference、AtomicIntegerArray、AtomicLongArray
引用对象:WeakReference、SoftReference
awt相关类型:java.awt.Color、java.awt.Font、java.awt.Point、java.awt.Rectangle
jdk8特有类型(java.time包中):LocalDateTime、LocalDate、LocalTime、ZonedDateTime、OffsetDateTime、OffsetTime、ZoneOffset、ZoneRegion、Period、Duration、Instant
oracle特有类型(oracle.sql包中):DATE、TIMESTAMP
另外,fastjson还可以识别一些类型,不光可以识别这些类型,还可以识别这些类型的所有子类。由于不确定这些类具体有多少子类,不可能提前把这些子类的Class对象都添加到map中。因此采取的是,只要某一类型是这些可识别类型或其子类,则即时添加到SerializeConfig中。举个例子:fastjson可以识别所有Map接口的实现类,但不可能提前知道我们自定义的Map接口实现类(如:MyMap.class),所以当遇到这个自定义实现类的时候,才把映射关系添加到map中。
这些可识别的类型包括:
Map接口及其实现类
List接口及其实现类
Collection接口及其实现类
Date及其子类
JSONAware及其实现类
JSONSerializable接口及其实现类
JSONStreamAware接口及其实现类
枚举类型及其子类
数组类型
Throwable及其子类
TimeZone及其子类
Appendable及其子类
Charset及其子类
Enumeration及其子类
Calendar及其子类
Clob及其子类
除了以上提到的这些所有类型外,其他类型全部为不可识别类型。对于不可识别的类型,全部使用JavaBeanSerializer或者ASMJavaBeanSerializer的子类(asm动态生成)进行序列化。
SerializeConfig选择序列化器的逻辑如下:
public ObjectSerializer getObjectWriter(Class<?> clazz) { // 从已存在的映射关系中,查找序列化器 ObjectSerializer writer = get(clazz); // 如果没有找到 if (writer == null) { try { // 获取当前线程使用的类加载器 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 使用类加载器尝试加载"META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectSerializer" // 这个文件中保存的所有类(一行一个类的全限定名),并调用无参构造创建对象 for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { // 如果该类没有实现AutowiredObjectSerializer则忽略 if (!(o instanceof AutowiredObjectSerializer)) { continue; } AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; // 把这个序列化器可以处理的类型集合添加到map中 for (Type forType : autowired.getAutowiredFor()) { put(forType, autowired); } } } catch (ClassCastException ex) { // skip } // 再次尝试获取对象序列化器 writer = get(clazz); } // 如果还是没有找到 if (writer == null) { // 获取加载JSON类的类加载器 final ClassLoader classLoader = JSON.class.getClassLoader(); // 如果当前线程使用的不是这个类加载器,则再次重复上面的步骤 if (classLoader != Thread.currentThread().getContextClassLoader()) { try { for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { if (!(o instanceof AutowiredObjectSerializer)) { continue; } AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; for (Type forType : autowired.getAutowiredFor()) { put(forType, autowired); } } } catch (ClassCastException ex) { // skip } // 再次尝试获取 writer = get(clazz); } } // 如果仍找不到,则进行下面的逻辑处理 if (writer == null) { if (Map.class.isAssignableFrom(clazz)) { put(clazz, MapSerializer.instance); } else if (List.class.isAssignableFrom(clazz)) { put(clazz, ListSerializer.instance); } else if (Collection.class.isAssignableFrom(clazz)) { put(clazz, CollectionSerializer.instance); } else if (Date.class.isAssignableFrom(clazz)) { put(clazz, DateSerializer.instance); } else if (JSONAware.class.isAssignableFrom(clazz)) { put(clazz, JSONAwareSerializer.instance); } else if (JSONSerializable.class.isAssignableFrom(clazz)) { put(clazz, JSONSerializableSerializer.instance); } else if (JSONStreamAware.class.isAssignableFrom(clazz)) { put(clazz, JSONStreamAwareSerializer.instance); } else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) { put(clazz, EnumSerializer.instance); } else if (clazz.isArray()) { Class<?> componentType = clazz.getComponentType(); ObjectSerializer compObjectSerializer = getObjectWriter(componentType); put(clazz, new ArraySerializer(componentType, compObjectSerializer)); } else if (Throwable.class.isAssignableFrom(clazz)) { put(clazz, new ExceptionSerializer(clazz)); } else if (TimeZone.class.isAssignableFrom(clazz)) { put(clazz, TimeZoneCodec.instance); } else if (Appendable.class.isAssignableFrom(clazz)) { put(clazz, AppendableSerializer.instance); } else if (Charset.class.isAssignableFrom(clazz)) { put(clazz, CharsetCodec.instance); } else if (Enumeration.class.isAssignableFrom(clazz)) { put(clazz, EnumerationSeriliazer.instance); } else if (Calendar.class.isAssignableFrom(clazz)) { put(clazz, CalendarCodec.instance); } else if (Clob.class.isAssignableFrom(clazz)) { put(clazz, ClobSeriliazer.instance); } else { boolean isCglibProxy = false; boolean isJavassistProxy = false; for (Class<?> item : clazz.getInterfaces()) { if (item.getName().equals("net.sf.cglib.proxy.Factory") || item.getName().equals("org.springframework.cglib.proxy.Factory")) { isCglibProxy = true; break; } else if (item.getName().equals("javassist.util.proxy.ProxyObject")) { isJavassistProxy = true; break; } } if (isCglibProxy || isJavassistProxy) { Class<?> superClazz = clazz.getSuperclass(); ObjectSerializer superWriter = getObjectWriter(superClazz); put(clazz, superWriter); return superWriter; } if (Proxy.isProxyClass(clazz)) { put(clazz, createJavaBeanSerializer(clazz)); } else { put(clazz, createJavaBeanSerializer(clazz)); } } writer = get(clazz); } return writer; }