Jackson 在 Spring Boot 中的处理时间的逻辑

6 篇文章 0 订阅

加载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.Jdk8Modulecom.fasterxml.jackson.datatype.jsr310.JavaTimeModuleorg.joda.time.LocalDatecom.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类型的字段,则会通过OffsetTimeDeserializerwithDateFormat方法,将JsonFormat中的信息形成的DateTimeFormatter类型的对象,重新生成一个新的OffsetTimeDeserializer对象来进行反序列化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值