有道无术,术尚可求,有术无道,止于术。
本系列 Jackson 版本 2.17.0
源码地址:https://gitee.com/pearl-organization/study-jaskson-demo
1. 概述
ObjectMapper在执行过程中,需要获取到对应类型的序列化器或反序列化器,然后执行具体操作。例如在序列化时List<T>,需要获取可以序列化List<T>类型的JsonSerializer(序列化器)。
这时需要使用到SerializerProvider,它是一个负责提供特定类型序列化器的抽象类,并实现了缓存功能。
2. DatabindContext
DatabindContext翻译过来是数据绑定上下文的意思,该抽象类声明了多个获取上下文相关信息的抽象方法,也提供了多个可以直接使用的普通⽅法供子类直接调用。
DatabindContext有两个重要的实现子类,它们是用于数据绑定过程中的关键上下文对象:
声明了多个用于获取配置的抽象方法:
/**
* 获取 MapperConfig
*/
public abstract MapperConfig<?> getConfig();
/**
* 获取 AnnotationIntrospector
*/
public abstract AnnotationIntrospector getAnnotationIntrospector();
// 查询某个MapperFeature 是否开启
public abstract boolean isEnabled(MapperFeature feature);
// 查询某个DatatypeFeature 是否开启
public abstract boolean isEnabled(DatatypeFeature feature);
// 获取 DatatypeFeatures
public abstract DatatypeFeatures getDatatypeFeatures();
// 查询是否允许覆盖访问修饰符
public abstract boolean canOverrideAccessModifiers();
// 获取当前正在使用的视图对象
public abstract Class<?> getActiveView();
// 获取当前正在使用的Locale
public abstract Locale getLocale();
// 获取当前正在使用的TimeZone
public abstract TimeZone getTimeZone();
// 获取@JsonFormat标注的信息
public abstract JsonFormat.Value getDefaultPropertyFormat(Class<?> baseType);
用于在上下文中设置和获取属性的抽象方法:
/**
* 获取上下文中可用的属性,每次调用的属性具有最高优先级,通过 {@link ObjectReader} 或 {@link ObjectWriter} 设置的属性具有较低的优先级。
*
* @param key 要获取的属性的键
* @return 如果存在,则返回属性的值;否则返回null
* @since 2.3
*/
public abstract Object getAttribute(Object key);
/**
* 上下文中设置属性,会覆盖之前的
*
* @param key 要设置的属性的键
* @param value 要设置的属性值
* @return 此上下文对象,以支持链式调用
* @since 2.3
*/
public abstract DatabindContext setAttribute(Object key, Object value);
JavaType是Jackson中用于表示Java类型信息的类,用于在序列化和反序列化JSON时正确处理不同类型的Java对象。 DatabindContext提供了将JDK类型转为JavaType的普通方法:
public JavaType constructType(Type type) {
if (type == null) {
return null;
}
return getTypeFactory().constructType(type);
}
提供了多个类型实例化和解析过程中,需要处理泛型擦除、多态的普通方法:
// 在构建过程中会保留泛型(避免泛型擦除)来构建子类型
public abstract JavaType constructSpecializedType(JavaType baseType, Class<?> subclass);
// 多态处理过程中,解析出子类的类名
public JavaType resolveSubType(JavaType baseType, String subClassName) throws JsonMappingException {
// ........
}
// 多态处理抛出异常
protected <T> T _throwNotASubtype(JavaType baseType, String subType) throws JsonMappingException {
throw invalidTypeIdException(baseType, subType, "Not a subtype");
}
protected <T> T _throwSubtypeNameNotAllowed(JavaType baseType, String subType, PolymorphicTypeValidator ptv) throws JsonMappingException {
// ........
}
protected <T> T _throwSubtypeClassNotAllowed(JavaType baseType, String subType, PolymorphicTypeValidator ptv) throws JsonMappingException {
// ........
}
3. SerializerProvider
SerializerProvider继承自DatabindContext,也是一个抽象类,ObjectMapper和JsonSerializers通过它获取特定类型的序列化器,并实现了缓存功能,当多次需要同一类型的序列化器时,先从缓存中查询。
3.1 成员属性
SerializerProvider提供了很多成员属性:
// 未知的映射是否进行缓存,可以加快解析速度
protected final static boolean CACHE_UNKNOWN_MAPPINGS = false;
// 默认的 Map 中的 Null 键序列化器,会直接抛出异常
public final static JsonSerializer<Object> DEFAULT_NULL_KEY_SERIALIZER =
new FailingSerializer("Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)");
// 用于处理java.lang.Object类型属性的默认序列化器
protected final static JsonSerializer<Object> DEFAULT_UNKNOWN_SERIALIZER = new UnknownSerializer();
// 序列化配置
protected final SerializationConfig _config;
// 视图
protected final Class<?> _serializationView;
// 用于构建序列化器实例的工厂
protected final SerializerFactory _serializerFactory;
// 序列化器缓存
protected final SerializerCache _serializerCache;
// 上下文属性
protected transient ContextAttributes _attributes;
// 未知类型的序列化器,默认的会抛出异常
protected JsonSerializer<Object> _unknownTypeSerializer = DEFAULT_UNKNOWN_SERIALIZER;
// Map 中键的序列化器
protected JsonSerializer<Object> _keySerializer;
// null 值序列化器,默认调用 JsonGenerator#writeNull
protected JsonSerializer<Object> _nullValueSerializer = NullSerializer.instance;
// Map 中的 Null 键的序列化器,默认的会抛出异常
protected JsonSerializer<Object> _nullKeySerializer = DEFAULT_NULL_KEY_SERIALIZER;
// 本地非共享、只读的一个MAP,用于快速查找之前已经获取过的序列化器
protected final ReadOnlyClassToSerializerMap _knownSerializers;
// 日期格式化器
protected DateFormat _dateFormat;
// 是否使用的是标准的 NullValueSerializer
protected final boolean _stdNullValueSerializer;
3.2 构造方法
SerializerProvider的构造方法,主要是对成员属性进行赋值:
public SerializerProvider()
{
_serializerCache = new SerializerCache();
// 省略...........
_stdNullValueSerializer = true;
}
protected SerializerProvider(SerializerProvider src,
SerializationConfig config, SerializerFactory f)
{
// 省略...........
_stdNullValueSerializer = (_nullValueSerializer == DEFAULT_NULL_KEY_SERIALIZER);
_knownSerializers = _serializerCache.getReadOnlyLookupMap();
}
3.3 setter & getter & isXx
我们在构建JsonMapper、ObjectMapper对象后,可以获取SerializerProvider对象,然后调用setter/getter/isXx方法。
示例代码:
JsonMapper jsonMapper = JsonMapper.builder().build();
SerializerProvider serializerProvider = jsonMapper.getSerializerProvider();
JsonSerializer<Object> defaultNullValueSerializer = serializerProvider.getDefaultNullValueSerializer(); // 获取默认的null 值序列化器
getter方法获取成员属性:
setter方法设置属性:
isXx方法查询:
3.4 findXx
提供了多个findXx方法用于查询序列化器:
3.5 defaultXx
提供了多个defaultXx用于默认的特定类型的序列化处理:
3.5 reportXx
提供了多个reportXx用于抛出序列化异常:
4. DefaultSerializerProvider
DefaultSerializerProvider是SerializerProvider的标准抽象实现,所有自定义的SerializerProvider实现都必须基于这个类。
DefaultSerializerProvider中已经提供了调用序列化器执行操作的可用方法:
提供了一个可用的Impl内部类,可以看到它基本没有什么处理逻辑,都交给了抽象类去完成:
public final static class Impl extends DefaultSerializerProvider {
private static final long serialVersionUID = 1L;
public Impl() { super(); }
public Impl(Impl src) { super(src); }
protected Impl(SerializerProvider src, SerializationConfig config,
SerializerFactory f) {
super(src, config, f);
}
/**
* @since 2.16
*/
protected Impl(Impl src, CacheProvider cp) {
super(src, cp);
}
@Override
public DefaultSerializerProvider copy()
{
return new Impl(this);
}
@Override
public Impl createInstance(SerializationConfig config, SerializerFactory jsf) {
return new Impl(this, config, jsf);
}
@Override
public DefaultSerializerProvider withCaches(CacheProvider cp) {
return new Impl(this, cp);
}
}
}
5. DeserializationContext
这里简单提一下DeserializationContext,因为它的继承结构、方法、属性等都和SerializerProvider差不多,不过是用于反序列化处理。