Jackson 2.x 系列【18】序列化器创建工厂 SerializerFactory

310 阅读3分钟

有道无术,术尚可求,有术无道,止于术。

本系列 Jackson 版本 2.17.0

源码地址:https://gitee.com/pearl-organization/study-jaskson-demo

1. 概述

在上一篇文档中,我们学习了SerializerProvider负责提供特定类型的序列化器,那么序列化器是如何创建的呢,接下来一起学习SerializerFactory来回应这个问题。

2. SerializerFactory

SerializerFactory抽象类提供给SerializerProvider用于创建JsonSerializer实例,以执行序列化操作。定义了抽象类可以让序列化过程可以更加灵活和定制化,具体的实现细节和策略则留给继承这个抽象类的子类来实现。

SerializerFactory继承结构如下:

image.png

SerializerFactory声明了三个with开头的抽象方法:

    public abstract SerializerFactory withAdditionalSerializers(Serializers additional);

    public abstract SerializerFactory withAdditionalKeySerializers(Serializers additional);

    public abstract SerializerFactory withSerializerModifier(BeanSerializerModifier modifier);

withAdditionalSerializerswithAdditionalKeySerializers方法创建一个新的工厂实例,并在创建过程中添加额外的序列化器,在自定义序列化器的时候回用到,示例代码如下:

        // 创建 ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 获取原有的 SerializerFactory
        SerializerFactory serializerFactory = objectMapper.getSerializerFactory();
        // 创建额外序列化器
        SimpleSerializers simpleSerializers=new SimpleSerializers();
        simpleSerializers.addSerializer(new SqlBlobSerializer());
        // SerializerFactory 添加自定义的序列化器
         SerializerFactory newSerializerFactory = serializerFactory.withAdditionalSerializers(simpleSerializers);
        // 重新设置给 ObjectMapper(因为SerializerFactory 是不可变对象, with 方法返回新的实例)
        objectMapper.setSerializerFactory(newSerializerFactory);

withSerializerModifier方法创建一个新的工厂实例,并在创建过程中添加额外的BeanSerializerModifier

Java BeanJSON的转换过程是比较复杂的,因为一般对象都包含了多种类型的属性, 之前有了解过Java Bean调用的是BeanSerializer执行的序列化,而BeanSerializerModifier则是这个序列化类的修改器,Jackson提供了扩展机制用于添加一些自定义的处理逻辑。

此外还声明了多个创建序列化器的方法:

    /**
     * 给指定的类型创建序列化器,对于不可变的序列化器,这个方法可能会选择重用现有的序列化器实例,而不是创建一个新的。
     *
     * @param prov     SerializerProvider(提供者,仅用于解析由注解指定的序列化器,而不用于其他类型的序列化器)
     * @param baseType 声明的类型,用作类型信息序列化器的基础类型
     * @return
     * @throws JsonMappingException
     */
    public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov,
                                                            JavaType baseType)
            throws JsonMappingException;

    public abstract TypeSerializer createTypeSerializer(SerializationConfig config,
                                                        JavaType baseType)
            throws JsonMappingException;

    // 创建负责处理 Map 的键的序列化器
    public JsonSerializer<Object> createKeySerializer(SerializerProvider prov,
                                                      JavaType type, JsonSerializer<Object> defaultImpl)
            throws JsonMappingException {
        return createKeySerializer(prov.getConfig(), type, defaultImpl);
    }

    @Deprecated // since 2.11
    public abstract JsonSerializer<Object> createKeySerializer(SerializationConfig config,
                                                               JavaType type, JsonSerializer<Object> defaultImpl)
            throws JsonMappingException;

3. BasicSerializerFactory

BasicSerializerFactory也是一个抽象类,继承自SerializerFactory,用于为标准的JDK类提供序列化器, 例如StringIntegerDate这些类型,可以直接由该工厂提供合适的序列化器。

该类的静态代码块中,预先实例化了很多JDK类对应的序列化器:

    static {
        HashMap<String, Class<? extends JsonSerializer<?>>> concLazy
            = new HashMap<String, Class<? extends JsonSerializer<?>>>();
        HashMap<String, JsonSerializer<?>> concrete
            = new HashMap<String, JsonSerializer<?>>();

		
        /* String and string-like types (note: date types explicitly
         * not included -- can use either textual or numeric serialization)
         */
        concrete.put(String.class.getName(), new StringSerializer());
        final ToStringSerializer sls = ToStringSerializer.instance;
        concrete.put(StringBuffer.class.getName(), sls);
        concrete.put(StringBuilder.class.getName(), sls);


        // Primitives/wrappers for primitives (primitives needed for Beans)
        NumberSerializers.addAll(concrete);
        concrete.put(Boolean.TYPE.getName(), new BooleanSerializer(true));
        concrete.put(Boolean.class.getName(), new BooleanSerializer(false));

        // Other numbers, more complicated

		// 省略........
        _concrete = concrete;
        _concreteLazy = concLazy;
    }

image.png 实现了父类的 with方法(其他抽象方法也基本实现了): image.png 提供了很多创建特定类型序列化器的方法: image.png 提供了很多查询序列化器的方法:

image.png

4. BeanSerializerFactory

BeanSerializerFactory继承自BasicSerializerFactory,是一个可以为任意Java Bean和标准JDK类提供序列化器的工厂类。

BeanSerializerFactory主要是重写了createSerializer方法: image.png

5. DeserializerFactory

DeserializerFactory抽象类提供给DeserializationContext用于创建JsonDeserializer实例,以反执行序列化操作。

image.pngDeserializationContext中可以看到DeserializerFactory类型的成员变量:

image.png

其结构、属性、方法都和SerializerFactory差不多,所以这里也只是简单带过,比如多个with方法用于创建新的工厂实例:

    public abstract DeserializerFactory withAdditionalDeserializers(Deserializers additional);

    public abstract DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional);

    public abstract DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier);

    public abstract DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver);

    public abstract DeserializerFactory withValueInstantiators(ValueInstantiators instantiators);

其他方法如下: image.png 创建ObjectMapper时,可以对DeserializerFactory进行扩展:

        // 创建 ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        // 获取原有的 DeserializationContext
        DeserializationContext deserializationContext = objectMapper.getDeserializationContext();
        // 获取原有的 DeserializerFactory
        DeserializerFactory deserializerFactory = deserializationContext.getFactory();
        // 设置 BeanDeserializerModifier
        DeserializerFactory newDeserializerFactory=deserializerFactory.withDeserializerModifier(new BeanDeserializerModifier() {
        });
        // 重新设置给 ObjectMapper(因为DeserializerFactory 是不可变对象, with 方法返回新的实例)
        objectMapper.setDeserializerFactory(newDeserializerFactory);