5. JsonFactory工厂而已,还蛮有料,这是我没想到的(上)

简介: 5. JsonFactory工厂而已,还蛮有料,这是我没想到的(上)

前言


各位好,我是YourBatman。前面用四篇文章介绍完了Jackson底层流式API的读(JsonParser)、写(JsonGenerator)操作,我们清楚的知道,这哥俩都是abstract抽象类,使用时并没有显示的去new它们的(子类)实例,均通过一个工厂来搞定,这便就是本文的主角JsonFactory。


通过名称就知道,这是工厂设计模式。Jackson它并不建议你直接new读/写实例,因为那过于麻烦。为了对使用者屏蔽这些复杂的构造细节,于是就有了JsonFactory实例工厂的出现。


可能有的人会说,一个对象工厂有什么好了解的,很简单嘛。非也非也,一件事情本身的复杂度并不会凭空消失,而是从一个地方转移到另外一个地方,这另外一个地方指的就是JsonFactory。因此按照本系列的定位,了解它你绕不过去。


版本约定


  • Jackson版本:2.11.0
  • Spring Framework版本:5.2.6.RELEASE
  • Spring Boot版本:2.3.0.RELEASE


正文


JsonFactory是Jackson的(最)主要工厂类,用于 配置和构建JsonGenerator和JsonParser,这个工厂实例是线程安全的,因此可以重复使用。


作为一个实例工厂,它最重要的职责当然是创建实例对象。本工厂职责并不单一,它负责读、写两种实例的创建工作。


创建JsonGenerator实例

image.png


JsonGenerator它负责向目的地写数据,因此强调的是目的地在哪?如何写?


如截图所示,一共有六个重载方法用于构建JsonGenerator实例,多个重载方法目的是对使用者友好,我们可以认为最终效果是一样的。比如,底层实现是:


JsonFactory:
    @Override
    public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException {
        IOContext ctxt = _createContext(out, false);
        ctxt.setEncoding(enc);
    // 如果编码是UTF-8
        if (enc == JsonEncoding.UTF8) {
            return _createUTF8Generator(_decorate(out, ctxt), ctxt);
        }
        // 使用指定的编码把OutputStream包装为一个writer
        Writer w = _createWriter(out, enc, ctxt);
        return _createGenerator(_decorate(w, ctxt), ctxt);
    }


这就解释了,为何在详解JsonGenerator的这篇文章中,我一直以UTF8JsonGenerator作为实例进行讲解,因为例子中指定的编码就是UTF-8嘛。当然,即使你自己不显示的指定编码集,默认情况下Jackson也是使用UTF-8:



JsonFactory:
    @Override
    public JsonGenerator createGenerator(OutputStream out) throws IOException {
        return createGenerator(out, JsonEncoding.UTF8);
    }


示例:


@Test
public void test1() throws IOException {
    JsonFactory jsonFactory = new JsonFactory();
    JsonGenerator jsonGenerator1 = jsonFactory.createGenerator(System.out);
    JsonGenerator jsonGenerator2 = jsonFactory.createGenerator(System.out, JsonEncoding.UTF8);
    System.out.println(jsonGenerator1);
    System.out.println(jsonGenerator2);
}


运行程序,输出:

com.fasterxml.jackson.core.json.UTF8JsonGenerator@cb51256
com.fasterxml.jackson.core.json.UTF8JsonGenerator@59906517



创建JsonParser实例


image.png

JsonParser它负责从一个JSON字符串中提取出值,因此它强调的是数据从哪来?如何解析?


如截图所示,一共11个重载方法(其实最后一个不属于重载)用于构建JsonParser实例,它的底层实现是根据不同的数据媒介,使用了不同的处理方式,最终生成UTF8StreamJsonParser/ReaderBasedJsonParser。


你会发现这几个重载方法均无需我们指定编码集,那它是如何确定使用何种编码去解码形如byte[]数组这种数据来源的呢?这得益于其内部的编码自动发现机制实现,也就是ByteSourceJsonBootstrapper#detectEncoding()这个方法。


示例:


@Test
public void test2() throws IOException {
    JsonFactory jsonFactory = new JsonFactory();
    JsonParser jsonParser1 = jsonFactory.createParser("{}");
    // JsonParser jsonParser2 = jsonFactory.createParser(new FileReader("..."));
    JsonParser jsonParser3 = jsonFactory.createNonBlockingByteArrayParser();
    System.out.println(jsonParser1);
    // System.out.println(jsonParser2);
    System.out.println(jsonParser3);
}


运行程序,输出:

com.fasterxml.jackson.core.json.ReaderBasedJsonParser@5f3a4b84
com.fasterxml.jackson.core.json.async.NonBlockingJsonParser@27f723


创建非阻塞实例


值得注意的是,上面截图的11个方法中,最后一个并非重载。它创建的是一个非阻塞JSON解析器,也就是NonBlockingJsonParser,并且它还没有指定入参(数据源)。


NonBlockingJsonParser是Jackson在2.9版本新增的的一个解析器,目标是进一步提升效率、性能。但它也有局限的地方:只能解析使用UTF-8编码的内容,否则抛出异常


当然喽,现在UTF-8编码几乎成为了标准编码手段,问题不大。但是呢,我自己玩了玩NonBlockingJsonParser,发现复杂度增加不少(玩半天才玩明白😄),效果却并不显著,因此这里了解一下便可,至少目前不建议深入探究。


小贴士:不管是Spring还是Redis的反序列化,使用的均是普通的解析器(阻塞IO)。因为JSON解析过程从来都不会是性能瓶颈(特殊场景除外)



相关文章
|
12月前
|
消息中间件 设计模式 JavaScript
这样写代码,同事乐开花!上
这样写代码,同事乐开花!上
|
12月前
|
敏捷开发 测试技术 数据安全/隐私保护
这样写代码,同事乐开花!下
这样写代码,同事乐开花!下
|
12月前
|
消息中间件 JavaScript 小程序
这样写代码,同事乐开花
这样写代码,同事乐开花
|
数据可视化 JavaScript Devops
菜鸟教练的第一次登场
菜鸟教练的第一次登场
93 0
菜鸟教练的第一次登场
|
供应链 搜索推荐 前端开发
走进独自开,带你轻松干副业
独自开信息科技(上海)有限公司是一个拥有独立研发实力的技术团队。 独自开秉承独立、自由、开放的团队价值观,坚守长期主义,始终聚焦商品与服务交易的全流程,建设一个独立、自由、开源的PaaS平台。 独自开是一个基于商品与服务交易全流程的PaaS开发平台。 可以协助开发者独自开发一套系统。
198 0
|
JSON 安全 Java
5. JsonFactory工厂而已,还蛮有料,这是我没想到的
一件事情本身的复杂度并不会凭空消失,而是从一个地方转移到另外一个地方
1056 0
5. JsonFactory工厂而已,还蛮有料,这是我没想到的
|
安全 Java 程序员
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(下)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(下)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(下)
|
存储 JSON 缓存
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(中)
5. JsonFactory工厂而已,还蛮有料,这是我没想到的(中)
|
前端开发 JavaScript 开发者
副业刚需?同事就用这 10 个开源项目接私活!
副业刚需?同事就用这 10 个开源项目接私活!
145 0
副业刚需?同事就用这 10 个开源项目接私活!
|
Web App开发 编解码 缓存
云话题 | 第3期 你女朋友在买买买时,程序员小哥在干嘛?
年货节来了,你女朋友下单了吗?观看直播已经成为人们日常上网的习惯之一,直播购物作为其中的重要项目,销售额屡创新高。最近,天猫年货节刚刚开幕,淘宝直播中就涌入了不少的用户前来抢购,毕竟足不出户就可以买到全国甚至全球的年货,对热衷买买买的消费者们来说实在太方便了。那么,直播抢购背后到底蕴藏着哪些技术?平台在开发网络直播系统时为什么如此看重CDN?在高并发直播的当下,CDN的技术人员都需要关注什么?阿里云Edge Plus的第3期云话题,边缘酱将为你讲讲关于直播抢购与CDN的那些事。
4531 0
云话题 | 第3期 你女朋友在买买买时,程序员小哥在干嘛?

热门文章

最新文章