fastjson深度源码解析- 序列化(四) - json序列化实现解析

x33g5p2x  于2021-12-25 转载在 其他  
字(12.8k)|赞(0)|评价(0)|浏览(800)

概要

fastjson序列化主要使用入口就是在JSON.java类中,它提供非常简便和友好的api将java对象转换成json字符串。

JSON成员函数

  1. /** * 便捷序列化java对象,序列化对象可以包含任意泛型属性字段,但是不适用本身是泛型的对象。 * 默认序列化返回字符串,可以使用writeJSONString(Writer, Object, SerializerFeature[]) * 将序列化字符串输出到指定输出器中 */
  2. public static String toJSONString(Object object) {
  3. /** * 直接调用重载方法,将指定object序列化成json字符串,忽略序列化filter */
  4. return toJSONString(object, emptyFilters);
  5. }

使用便捷接口toJSONString方法,可以将任意java对象序列化为json字符串,内部调用toJSONString(Object, SerializeFilter[], SerializerFeature... ) :

  1. public static String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) {
  2. return toJSONString(object, SerializeConfig.globalInstance, filters, null, DEFAULT_GENERATE_FEATURE, features);
  3. }

继续跟踪方法调用到toJSONString(Object, SerializeConfig ,SerializeFilter[], String, int, SerializerFeature... ) :

  1. public static String toJSONString(Object object, /** 序列化对象 */
  2. SerializeConfig config, /** 全局序列化配置 */
  3. SerializeFilter[] filters, /** 序列化拦截器 */
  4. String dateFormat, /** 序列化日期格式 */
  5. int defaultFeatures, /** 默认序列化特性 */
  6. SerializerFeature... features) { /** 自定义序列化特性 */
  7. /** 初始化序列化writer,用features覆盖defaultFeatures配置 */
  8. SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);
  9. try {
  10. /** * 初始化JSONSerializer,序列化类型由它委托config查找具体 * 序列化处理器处理,序列化结果写入out的buffer中 */
  11. JSONSerializer serializer = new JSONSerializer(out, config);
  12. if (dateFormat != null && dateFormat.length() != 0) {
  13. serializer.setDateFormat(dateFormat);
  14. /** 调用out 重新配置属性 并且打开WriteDateUseDateFormat特性 */
  15. serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
  16. }
  17. if (filters != null) {
  18. for (SerializeFilter filter : filters) {
  19. /** 添加拦截器 */
  20. serializer.addFilter(filter);
  21. }
  22. }
  23. /** 使用序列化实例转换对象,查找具体序列化实例委托给config查找 */
  24. serializer.write(object);
  25. return out.toString();
  26. } finally {
  27. out.close();
  28. }
  29. }

这个序列化方法实际并不是真正执行序列化操作,首先做序列化特性配置,然后追加序列化拦截器,开始执行序列化对象操作委托给了config对象查找。

我们继续进入serializer.write(object) 查看:

  1. public final void write(Object object) {
  2. if (object == null) {
  3. /** 如果对象为空,直接输出 "null" 字符串 */
  4. out.writeNull();
  5. return;
  6. }
  7. Class<?> clazz = object.getClass();
  8. /** 根据对象的Class类型查找具体序列化实例 */
  9. ObjectSerializer writer = getObjectWriter(clazz);
  10. try {
  11. /** 使用具体serializer实例处理对象 */
  12. writer.write(this, object, null, null, 0);
  13. } catch (IOException e) {
  14. throw new JSONException(e.getMessage(), e);
  15. }
  16. }

序列化回调接口

ObjectSerializer序列化接口

我们发现真正序列化对象的时候是由具体ObjectSerializer实例完成,我们首先查看一下接口定义:

  1. void write(JSONSerializer serializer, /** json序列化实例 */
  2. Object object, /** 待序列化的对象*/
  3. Object fieldName, /** 待序列化字段*/
  4. Type fieldType, /** 待序列化字段类型 */
  5. int features) throws IOException;

当fastjson序列化特定的字段时会回调这个方法。

我们继续跟踪writer.write(this, object, null, null, 0) :

  1. public final void write(Object object) {
  2. if (object == null) {
  3. /** 如果对象为空,直接输出 "null" 字符串 */
  4. out.writeNull();
  5. return;
  6. }
  7. Class<?> clazz = object.getClass();
  8. /** 根据对象的Class类型查找具体序列化实例 */
  9. ObjectSerializer writer = getObjectWriter(clazz);
  10. try {
  11. /** 使用具体serializer实例处理对象 */
  12. writer.write(this, object, null, null, 0);
  13. } catch (IOException e) {
  14. throw new JSONException(e.getMessage(), e);
  15. }
  16. }

我们发现在方法内部调用getObjectWriter(clazz)根据具体类型查找序列化实例,方法内部只有一行调用 config.getObjectWriter(clazz),让我们更进一步查看委托实现细节com.alibaba.fastjson.serializer.SerializeConfig#getObjectWriter(java.lang.Class<?>):

  1. public ObjectSerializer getObjectWriter(Class<?> clazz) {
  2. return getObjectWriter(clazz, true);
  3. }

内部又调用com.alibaba.fastjson.serializer.SerializeConfig#getObjectWriter(java.lang.Class<?>, boolean),这个类实现相对复杂了一些,我会按照代码顺序梳理所有序列化实例的要点 :

  1. private ObjectSerializer getObjectWriter(Class<?> clazz, boolean create) {
  2. /** 首先从内部已经注册查找特定class的序列化实例 */
  3. ObjectSerializer writer = serializers.get(clazz);
  4. if (writer == null) {
  5. try {
  6. final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
  7. /** 使用当前线程类加载器 查找 META-INF/services/AutowiredObjectSerializer.class实现类 */
  8. for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
  9. if (!(o instanceof AutowiredObjectSerializer)) {
  10. continue;
  11. }
  12. AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
  13. for (Type forType : autowired.getAutowiredFor()) {
  14. /** 如果存在,注册到内部serializers缓存中 */
  15. put(forType, autowired);
  16. }
  17. }
  18. } catch (ClassCastException ex) {
  19. // skip
  20. }
  21. /** 尝试在已注册缓存找到特定class的序列化实例 */
  22. writer = serializers.get(clazz);
  23. }
  24. if (writer == null) {
  25. /** 使用加载JSON类的加载器 查找 META-INF/services/AutowiredObjectSerializer.class实现类 */
  26. final ClassLoader classLoader = JSON.class.getClassLoader();
  27. if (classLoader != Thread.currentThread().getContextClassLoader()) {
  28. try {
  29. for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
  30. if (!(o instanceof AutowiredObjectSerializer)) {
  31. continue;
  32. }
  33. AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
  34. for (Type forType : autowired.getAutowiredFor()) {
  35. /** 如果存在,注册到内部serializers缓存中 */
  36. put(forType, autowired);
  37. }
  38. }
  39. } catch (ClassCastException ex) {
  40. // skip
  41. }
  42. /** 尝试在已注册缓存找到特定class的序列化实例 */
  43. writer = serializers.get(clazz);
  44. }
  45. }
  46. if (writer == null) {
  47. String className = clazz.getName();
  48. Class<?> superClass;
  49. if (Map.class.isAssignableFrom(clazz)) {
  50. /** 如果class实现类Map接口,使用MapSerializer序列化 */
  51. put(clazz, writer = MapSerializer.instance);
  52. } else if (List.class.isAssignableFrom(clazz)) {
  53. /** 如果class实现类List接口,使用ListSerializer序列化 */
  54. put(clazz, writer = ListSerializer.instance);
  55. } else if (Collection.class.isAssignableFrom(clazz)) {
  56. /** 如果class实现类Collection接口,使用CollectionCodec序列化 */
  57. put(clazz, writer = CollectionCodec.instance);
  58. } else if (Date.class.isAssignableFrom(clazz)) {
  59. /** 如果class继承Date,使用DateCodec序列化 */
  60. put(clazz, writer = DateCodec.instance);
  61. } else if (JSONAware.class.isAssignableFrom(clazz)) {
  62. /** 如果class实现类JSONAware接口,使用JSONAwareSerializer序列化 */
  63. put(clazz, writer = JSONAwareSerializer.instance);
  64. } else if (JSONSerializable.class.isAssignableFrom(clazz)) {
  65. /** 如果class实现类JSONSerializable接口,使用JSONSerializableSerializer序列化 */
  66. put(clazz, writer = JSONSerializableSerializer.instance);
  67. } else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
  68. /** 如果class实现类JSONStreamAware接口,使用MiscCodecr序列化 */
  69. put(clazz, writer = MiscCodec.instance);
  70. } else if (clazz.isEnum()) {
  71. JSONType jsonType = TypeUtils.getAnnotation(clazz, JSONType.class);
  72. if (jsonType != null && jsonType.serializeEnumAsJavaBean()) {
  73. /** 如果是枚举类型,并且启用特性 serializeEnumAsJavaBean * 使用JavaBeanSerializer序列化(假设没有启用asm) */
  74. put(clazz, writer = createJavaBeanSerializer(clazz));
  75. } else {
  76. /** 如果是枚举类型,没有启用特性 serializeEnumAsJavaBean * 使用EnumSerializer序列化 */
  77. put(clazz, writer = EnumSerializer.instance);
  78. }
  79. } else if ((superClass = clazz.getSuperclass()) != null && superClass.isEnum()) {
  80. JSONType jsonType = TypeUtils.getAnnotation(superClass, JSONType.class);
  81. if (jsonType != null && jsonType.serializeEnumAsJavaBean()) {
  82. /** 如果父类是枚举类型,并且启用特性 serializeEnumAsJavaBean * 使用JavaBeanSerializer序列化(假设没有启用asm) */
  83. put(clazz, writer = createJavaBeanSerializer(clazz));
  84. } else {
  85. /** 如果父类是枚举类型,没有启用特性 serializeEnumAsJavaBean * 使用EnumSerializer序列化 */
  86. put(clazz, writer = EnumSerializer.instance);
  87. }
  88. } else if (clazz.isArray()) {
  89. Class<?> componentType = clazz.getComponentType();
  90. /** 如果是数组类型,根据数组实际类型查找序列化实例 */
  91. ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
  92. put(clazz, writer = new ArraySerializer(componentType, compObjectSerializer));
  93. } else if (Throwable.class.isAssignableFrom(clazz)) {
  94. /** 注册通用JavaBeanSerializer序列化处理 Throwable */
  95. SerializeBeanInfo beanInfo = TypeUtils.buildBeanInfo(clazz, null, propertyNamingStrategy);
  96. beanInfo.features |= SerializerFeature.WriteClassName.mask;
  97. put(clazz, writer = new JavaBeanSerializer(beanInfo));
  98. } else if (TimeZone.class.isAssignableFrom(clazz) || Map.Entry.class.isAssignableFrom(clazz)) {
  99. /** 如果class实现Map.Entry接口或者继承类TimeZone,使用MiscCodecr序列化 */
  100. put(clazz, writer = MiscCodec.instance);
  101. } else if (Appendable.class.isAssignableFrom(clazz)) {
  102. /** 如果class实现Appendable接口,使用AppendableSerializer序列化 */
  103. put(clazz, writer = AppendableSerializer.instance);
  104. } else if (Charset.class.isAssignableFrom(clazz)) {
  105. /** 如果class继承Charset抽象类,使用ToStringSerializer序列化 */
  106. put(clazz, writer = ToStringSerializer.instance);
  107. } else if (Enumeration.class.isAssignableFrom(clazz)) {
  108. /** 如果class实现Enumeration接口,使用EnumerationSerializer序列化 */
  109. put(clazz, writer = EnumerationSerializer.instance);
  110. } else if (Calendar.class.isAssignableFrom(clazz)
  111. || XMLGregorianCalendar.class.isAssignableFrom(clazz)) {
  112. /** 如果class继承类Calendar或者XMLGregorianCalendar,使用CalendarCodec序列化 */
  113. put(clazz, writer = CalendarCodec.instance);
  114. } else if (Clob.class.isAssignableFrom(clazz)) {
  115. /** 如果class实现Clob接口,使用ClobSeriliazer序列化 */
  116. put(clazz, writer = ClobSeriliazer.instance);
  117. } else if (TypeUtils.isPath(clazz)) {
  118. /** 如果class实现java.nio.file.Path接口,使用ToStringSerializer序列化 */
  119. put(clazz, writer = ToStringSerializer.instance);
  120. } else if (Iterator.class.isAssignableFrom(clazz)) {
  121. /** 如果class实现Iterator接口,使用MiscCodec序列化 */
  122. put(clazz, writer = MiscCodec.instance);
  123. } else {
  124. /** * 如果class的name是"java.awt."开头 并且 * 继承 Point、Rectangle、Font或者Color 其中之一 */
  125. if (className.startsWith("java.awt.")
  126. && AwtCodec.support(clazz)
  127. ) {
  128. // awt
  129. if (!awtError) {
  130. try {
  131. String[] names = new String[]{
  132. "java.awt.Color",
  133. "java.awt.Font",
  134. "java.awt.Point",
  135. "java.awt.Rectangle"
  136. };
  137. for (String name : names) {
  138. if (name.equals(className)) {
  139. /** 如果系统支持4中类型, 使用AwtCodec 序列化 */
  140. put(Class.forName(name), writer = AwtCodec.instance);
  141. return writer;
  142. }
  143. }
  144. } catch (Throwable e) {
  145. awtError = true;
  146. // skip
  147. }
  148. }
  149. }
  150. // jdk8
  151. if ((!jdk8Error) //
  152. && (className.startsWith("java.time.") //
  153. || className.startsWith("java.util.Optional") //
  154. || className.equals("java.util.concurrent.atomic.LongAdder")
  155. || className.equals("java.util.concurrent.atomic.DoubleAdder")
  156. )) {
  157. try {
  158. {
  159. String[] names = new String[]{
  160. "java.time.LocalDateTime",
  161. "java.time.LocalDate",
  162. "java.time.LocalTime",
  163. "java.time.ZonedDateTime",
  164. "java.time.OffsetDateTime",
  165. "java.time.OffsetTime",
  166. "java.time.ZoneOffset",
  167. "java.time.ZoneRegion",
  168. "java.time.Period",
  169. "java.time.Duration",
  170. "java.time.Instant"
  171. };
  172. for (String name : names) {
  173. if (name.equals(className)) {
  174. /** 如果系统支持JDK8中日期类型, 使用Jdk8DateCodec 序列化 */
  175. put(Class.forName(name), writer = Jdk8DateCodec.instance);
  176. return writer;
  177. }
  178. }
  179. }
  180. {
  181. String[] names = new String[]{
  182. "java.util.Optional",
  183. "java.util.OptionalDouble",
  184. "java.util.OptionalInt",
  185. "java.util.OptionalLong"
  186. };
  187. for (String name : names) {
  188. if (name.equals(className)) {
  189. /** 如果系统支持JDK8中可选类型, 使用OptionalCodec 序列化 */
  190. put(Class.forName(name), writer = OptionalCodec.instance);
  191. return writer;
  192. }
  193. }
  194. }
  195. {
  196. String[] names = new String[]{
  197. "java.util.concurrent.atomic.LongAdder",
  198. "java.util.concurrent.atomic.DoubleAdder"
  199. };
  200. for (String name : names) {
  201. if (name.equals(className)) {
  202. /** 如果系统支持JDK8中原子类型, 使用AdderSerializer 序列化 */
  203. put(Class.forName(name), writer = AdderSerializer.instance);
  204. return writer;
  205. }
  206. }
  207. }
  208. } catch (Throwable e) {
  209. // skip
  210. jdk8Error = true;
  211. }
  212. }
  213. if ((!oracleJdbcError) //
  214. && className.startsWith("oracle.sql.")) {
  215. try {
  216. String[] names = new String[] {
  217. "oracle.sql.DATE",
  218. "oracle.sql.TIMESTAMP"
  219. };
  220. for (String name : names) {
  221. if (name.equals(className)) {
  222. /** 如果系统支持oralcle驱动中日期类型, 使用DateCodec 序列化 */
  223. put(Class.forName(name), writer = DateCodec.instance);
  224. return writer;
  225. }
  226. }
  227. } catch (Throwable e) {
  228. // skip
  229. oracleJdbcError = true;
  230. }
  231. }
  232. if ((!springfoxError) //
  233. && className.equals("springfox.documentation.spring.web.json.Json")) {
  234. try {
  235. /** 如果系统支持springfox-spring-web框架中Json类型, 使用SwaggerJsonSerializer 序列化 */
  236. put(Class.forName("springfox.documentation.spring.web.json.Json"),
  237. writer = SwaggerJsonSerializer.instance);
  238. return writer;
  239. } catch (ClassNotFoundException e) {
  240. // skip
  241. springfoxError = true;
  242. }
  243. }
  244. if ((!guavaError) //
  245. && className.startsWith("com.google.common.collect.")) {
  246. try {
  247. String[] names = new String[] {
  248. "com.google.common.collect.HashMultimap",
  249. "com.google.common.collect.LinkedListMultimap",
  250. "com.google.common.collect.ArrayListMultimap",
  251. "com.google.common.collect.TreeMultimap"
  252. };
  253. for (String name : names) {
  254. if (name.equals(className)) {
  255. /** 如果系统支持guava框架中日期类型, 使用GuavaCodec 序列化 */
  256. put(Class.forName(name), writer = GuavaCodec.instance);
  257. return writer;
  258. }
  259. }
  260. } catch (ClassNotFoundException e) {
  261. // skip
  262. guavaError = true;
  263. }
  264. }
  265. if ((!jsonnullError) && className.equals("net.sf.json.JSONNull")) {
  266. try {
  267. /** 如果系统支持json-lib框架中JSONNull类型, 使用MiscCodec 序列化 */
  268. put(Class.forName("net.sf.json.JSONNull"), writer = MiscCodec.instance);
  269. return writer;
  270. } catch (ClassNotFoundException e) {
  271. // skip
  272. jsonnullError = true;
  273. }
  274. }
  275. Class[] interfaces = clazz.getInterfaces();
  276. /** 如果class只实现唯一接口,并且接口包含注解,使用AnnotationSerializer 序列化 */
  277. if (interfaces.length == 1 && interfaces[0].isAnnotation()) {
  278. return AnnotationSerializer.instance;
  279. }
  280. /** 如果使用了cglib或者javassist动态代理 */
  281. if (TypeUtils.isProxy(clazz)) {
  282. Class<?> superClazz = clazz.getSuperclass();
  283. /** 通过父类型查找序列化,父类是真实的类型 */
  284. ObjectSerializer superWriter = getObjectWriter(superClazz);
  285. put(clazz, superWriter);
  286. return superWriter;
  287. }
  288. /** 如果使用了jdk动态代理 */
  289. if (Proxy.isProxyClass(clazz)) {
  290. Class handlerClass = null;
  291. if (interfaces.length == 2) {
  292. handlerClass = interfaces[1];
  293. } else {
  294. for (Class proxiedInterface : interfaces) {
  295. if (proxiedInterface.getName().startsWith("org.springframework.aop.")) {
  296. continue;
  297. }
  298. if (handlerClass != null) {
  299. handlerClass = null; // multi-matched
  300. break;
  301. }
  302. handlerClass = proxiedInterface;
  303. }
  304. }
  305. if (handlerClass != null) {
  306. /** 根据class实现接口类型查找序列化 */
  307. ObjectSerializer superWriter = getObjectWriter(handlerClass);
  308. put(clazz, superWriter);
  309. return superWriter;
  310. }
  311. }
  312. if (create) {
  313. /** 没有精确匹配,使用通用JavaBeanSerializer 序列化(假设不启用asm) */
  314. writer = createJavaBeanSerializer(clazz);
  315. put(clazz, writer);
  316. }
  317. }
  318. if (writer == null) {
  319. /** 尝试在已注册缓存找到特定class的序列化实例 */
  320. writer = serializers.get(clazz);
  321. }
  322. }
  323. return writer;
  324. }

查找具体序列化实例,查找方法基本思想根据class类型或者实现接口类型进行匹配查找。接下来针对逐个序列化实现依次分析。

相关文章