加载Jackson
在org.springframework.boot.autoconfigure.BackgroundPreinitializer
中通过监听ApplicationStartingEvent
事件,执行performPreinitialization()
方法。
private void performPreinitialization() {
try {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());//@1
runSafely(new JacksonInitializer());
runSafely(new CharsetInitializer());
preinitializationComplete.countDown();
}
public void runSafely(Runnable runnable) {
try {
runnable.run();
}
catch (Throwable ex) {
// Ignore
}
}
}, "background-preinit");
thread.start();
}
catch (Exception ex) {
// This will fail on GAE where creating threads is prohibited. We can safely
// continue but startup will be slightly slower as the initialization will now
// happen on the main thread.
preinitializationComplete.countDown();
}
}
该方法启动了一个线程,在线程里@1位置直接运行MessageConverterInitializer
内部的run()
方法,内部只有一行代码new AllEncompassingFormHttpMessageConverter();
。
这个类代码非常短,功能看一眼就懂,通过判断某个json处理类存不存在于classLoader中,在构造器中依据判断结果调用addPartConverter
方法。我省略了一些代码。
public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter {
private static final boolean jackson2Present;
……
static {
ClassLoader classLoader = AllEncompassingFormHttpMessageConverter.class.getClassLoader();
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
}
public AllEncompassingFormHttpMessageConverter() {
try {
addPartConverter(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
……
if (jackson2Present) {
addPartConverter(new MappingJackson2HttpMessageConverter());
}
……
}
}
MappingJackson2HttpMessageConverter
的构造器如下:
public MappingJackson2HttpMessageConverter() {
this(Jackson2ObjectMapperBuilder.json().build());
}
json()
构造了一个Jackson2ObjectMapperBuilder
对象,而build()
则是为了获得ObjectMapper
对象。
在build
方法中有一处代码configure(mapper);
,其内部会通过registerWellKnownModulesIfAvailable(modulesToRegister);
注册com.fasterxml.jackson.datatype.jdk8.Jdk8Module
、com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
、org.joda.time.LocalDate
、com.fasterxml.jackson.module.kotlin.KotlinModule
。
这样,JavaTime相关的序列化器和反序列化起就通过JavaTimeModule
被配置了进来。
比如,我们以com.fasterxml.jackson.datatype.jsr310.deser.OffsetTimeDeserializer
举例。由于是调用无参构造器。
private OffsetTimeDeserializer() {
this(DateTimeFormatter.ISO_OFFSET_TIME);
}
可以看见其默认采用DateTimeFormatter.ISO_OFFSET_TIME
。
使用
平常的OffsetDateTime
类型的字段,默认使用DateTimeFormatter.ISO_OFFSET_TIME
反序列化,格式为"2020-07-24T02:26:24Z"。
对于注解了类似@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
这样的注解OffsetDateTime
类型的字段,则会通过OffsetTimeDeserializer
中withDateFormat
方法,将JsonFormat
中的信息形成的DateTimeFormatter
类型的对象,重新生成一个新的OffsetTimeDeserializer
对象来进行反序列化。