Jackson 2.x 系列【25】Spring Boot 集成之起步依赖、自动配置

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

本系列Jackson 版本 2.17.0

本系列Spring Boot 版本 3.2.4

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

文章目录

    • 1. 前言
    • 2. 起步依赖
    • 3. 自动配置
      • 3.1 JacksonProperties
      • 3.2 JacksonAutoConfiguration
        • 3.2.1 JacksonMixinConfiguration
        • 3.2.2 JacksonObjectMapperBuilderConfiguration
        • 3.2.3 JacksonObjectMapperConfiguration
        • 3.2.4 ParameterNamesModuleConfiguration
        • 3.2.5 Jackson2ObjectMapperBuilderCustomizerConfiguration
    • 4. Jackson2ObjectMapperBuilderCustomizer

1. 前言

Spring Boot是当前最流行的Java应用开发框架,简化开发的同时也导致了很多开发人员只会写业务代码,并不太清楚内部组件和配置细节,一旦出问题或者需要性能优化时,就会显得无从下手。

所以推荐大家要多学习一下基础的应用框架,了解它们的详细用法和核心原理,不要太依赖于Spring Boot的自动化。

接下来我们学习Spring Boot是如何集成的Jackson,并针对开发中常见的问题进行实战演示。

2. 起步依赖

Spring Boot起步依赖(Starter Dependency)机制,针对常见场景需要的依赖进行了统一打包处理,使用时只需要引入Starter包即可。

例如针对JSON应用场景,在Spring Boot中提供了spring-boot-starter-json启动器,默认引入的JSON库是Jackson

dependencies {
	api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))
	api("org.springframework:spring-web")
	api("com.fasterxml.jackson.core:jackson-databind")
	api("com.fasterxml.jackson.datatype:jackson-datatype-jdk8")
	api("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
	api("com.fasterxml.jackson.module:jackson-module-parameter-names")
}

除了jackson-databind,还引入非核心模块jackson-datatype-jdk8jackson-datatype-jsr310jackson-module-parameter-names,所以在Spring Boot环境中,可以直接处理LocalDateTime

3. 自动配置

Spring Boot基于约定大于配置思想,引入了Starter包后,启动时扫描自动配置类,并自动装配声明的Bean组件,开发者无需手动进行繁琐的配置,从而提高了开发效率,降低了维护成本。

spring-boot-autoconfigure模块中包含了对Jackson的自动配置:

在这里插入图片描述

3.1 JacksonProperties

Spring Boot 提供了配置属性类JacksonProperties,方便我们直接在application.yml配置文件中指定一些转换策略:
在这里插入图片描述

全部属性配置如下:

spring:
  jackson:
    constructor-detector: EXPLICIT_ONLY
    # 设置日志格式化格式,配置为日期格式字符串或完全限定的日期格式类名。例如 yyyy-MM-dd HH:mm:ss
    date-format: yyyy-MM-dd HH:mm:ss
    # 宽松的全局默认设置
    default-leniency: true
    # 控制序列化期间包含的属性。使用 Jackson 的 JsonInclude.Include 枚举中的值之一进行配置。
    default-property-inclusion: always
    # 序列化配置 ,MAP 集合 , Map<SerializationFeature, Boolean>
    serialization:
      EAGER_SERIALIZER_FETCH: true
    # 反序列化特征,Map<DeserializationFeature, Boolean>
    deserialization:
      USE_BIG_DECIMAL_FOR_FLOATS: true
    # ObjectMapper/JsonMapper特征,Map<MapperFeature, Boolean>
    mapper:
      AUTO_DETECT_GETTERS: true
    # 生成器JsonGenerator.Feature,Map<com.fasterxml.jackson.core.JsonGenerator.Feature, Boolean>
    generator:
      AUTO_CLOSE_TARGET: true
    # 地区
    locale: zh_CN
    # 解析器 Map<Feature, Boolean>
    # parser:
    # 设置属性命名策略,对应jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json驼峰式转下划线,json body下划线传到后端自动转驼峰式
    property-naming-strategy: SNAKE_CASE
    # 全局时区
    time-zone: GMT+8
    # 可见性阈值,可用于限制自动检测哪些方法(和字段)。
    visibility:
      GETTER: ANY

3.2 JacksonAutoConfiguration

Spring Boot 提供了自动配置类JacksonAutoConfiguration,包含了多个内部配置类:

在这里插入图片描述
在自动配置类的static 块中,配置了两个默认特征,设置序列化日志时间不使用时间戳,并注册JsonComponentModule Bean 对象,用于注册所有@JsonComponent标识的Bean

@AutoConfiguration
@ConditionalOnClass({ObjectMapper.class})
public class JacksonAutoConfiguration {

    @Bean
    public JsonComponentModule jsonComponentModule() {
        return new JsonComponentModule();
    }
    
    private static final Map<?, Boolean> FEATURE_DEFAULTS;
    
    static {
        Map<Object, Boolean> featureDefaults = new HashMap();
        featureDefaults.put(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        featureDefaults.put(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
        FEATURE_DEFAULTS = Collections.unmodifiableMap(featureDefaults);
    }
    // 省略内部配置类
3.2.1 JacksonMixinConfiguration

内部自动配置类JacksonMixinConfiguration用于扫描@JsonMixin标识的类并注册,以支持混合注解:

	@Configuration(proxyBeanMethods = false)
	static class JacksonMixinConfiguration {
		@Bean
		static JsonMixinModuleEntries jsonMixinModuleEntries(ApplicationContext context) {
			List<String> packages = AutoConfigurationPackages.has(context) ? AutoConfigurationPackages.get(context)
					: Collections.emptyList();
			return JsonMixinModuleEntries.scan(context, packages);
		}
		@Bean
		JsonMixinModule jsonMixinModule(ApplicationContext context, JsonMixinModuleEntries entries) {
			JsonMixinModule jsonMixinModule = new JsonMixinModule();
			jsonMixinModule.registerEntries(entries, context.getClassLoader());
			return jsonMixinModule;
		}
	}
3.2.2 JacksonObjectMapperBuilderConfiguration

内部自动配置类JacksonObjectMapperBuilderConfiguration 注册了一个多例的Jackson2ObjectMapperBuilder(用于构建ObjectMapper对象),并调用所有的定制器Jackson2ObjectMapperBuilderCustomizer进行定制化处理:

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
	static class JacksonObjectMapperBuilderConfiguration {

		@Bean
		@Scope("prototype")
		@ConditionalOnMissingBean
		Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(ApplicationContext applicationContext,
				List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
			Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
			builder.applicationContext(applicationContext);
			customize(builder, customizers);
			return builder;
		}

		private void customize(Jackson2ObjectMapperBuilder builder,
				List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
			for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
				customizer.customize(builder);
			}
		}

	}
3.2.3 JacksonObjectMapperConfiguration

内部自动配置类JacksonObjectMapperConfiguration 注册了一个单例的ObjectMapper Bean 对象到容器中,是使用容器中的Jackson2ObjectMapperBuilder 构建的,并且是线程安全的,所以在使用时直接使用@Autowired注入该实例即可。

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
	static class JacksonObjectMapperConfiguration {
		@Bean
		@Primary // 主要的
		@ConditionalOnMissingBean // 在应用程序没有注册ObjectMapper时生效
		ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
			return builder.createXmlMapper(false).build();
		}
	}
3.2.4 ParameterNamesModuleConfiguration

内部自动配置类ParameterNamesModuleConfiguration 用于注册了ParameterNamesModule

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(ParameterNamesModule.class)
	static class ParameterNamesModuleConfiguration {

		@Bean
		@ConditionalOnMissingBean
		ParameterNamesModule parameterNamesModule() {
			return new ParameterNamesModule(JsonCreator.Mode.DEFAULT);
		}

	}
3.2.5 Jackson2ObjectMapperBuilderCustomizerConfiguration

内部自动配置类Jackson2ObjectMapperBuilderCustomizerConfiguration的主要作用是将JacksonPropertiesModule中的配置,集成到应用环境中。

注册了一个StandardJackson2ObjectMapperBuilderCustomizer

在这里插入图片描述

StandardJackson2ObjectMapperBuilderCustomizer实现了Jackson2ObjectMapperBuilderCustomizer,所以在自动注册Jackson2ObjectMapperBuilder时,会调用customize方法,将JacksonProperties的配置项都集成到Jackson2ObjectMapperBuilder中:

在这里插入图片描述

4. Jackson2ObjectMapperBuilderCustomizer

Jackson2ObjectMapperBuilderCustomizer定制器接口,用于对Jackson2ObjectMapperBuilder的构建行为进行定制:

@FunctionalInterface
public interface Jackson2ObjectMapperBuilderCustomizer {

	void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder);

}

他们之间的关系如下所示:
在这里插入图片描述

在实际开发中,可以注册Jackson2ObjectMapperBuilderCustomizer来配置ObjectMapper

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.serializerByType(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
            builder.deserializerByType(Long.class,com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        };
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/551120.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数学建模-最优包衣厚度终点判别法-二(K-Means聚类)

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是viperrrrrrr~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff…

PyTorch小技巧:使用Hook可视化网络层激活(各层输出)

这篇文章将演示如何可视化PyTorch激活层。可视化激活&#xff0c;即模型内各层的输出&#xff0c;对于理解深度神经网络如何处理视觉信息至关重要&#xff0c;这有助于诊断模型行为并激发改进。 我们先安装必要的库: pip install torch torchvision matplotlib加载CIFAR-10数据…

淘宝扭蛋机小程序开发:开启购物娱乐新纪元

在数字时代浪潮的推动下&#xff0c;小程序作为新兴的交互平台&#xff0c;正在不断引领着购物方式的革新。淘宝扭蛋机小程序的开发&#xff0c;便是这一变革中的一颗璀璨明星&#xff0c;它将传统扭蛋机的趣味与电商购物的便捷完美融合&#xff0c;为用户带来了前所未有的购物…

微服务整合Spring Cloud Gateway动态路由

前置 创建 Spring Cloud项目 参考&#xff1a;创建Spring Cloud Maven工程-CSDN博客 1. 创建一个maven jar类型项目 在idea中右键父工程-》New-》Module 创建一个maven工程 2. 引入相关依赖 在POM文件中引入下面的依赖 <project xmlns"http://maven.apache.org/P…

【C++】力扣OJ题:构建杨辉三角

Hello everybody!今天给大家介绍一道我认为比较经典的编程练习题&#xff0c;之所以介绍它是因为这道题涉及到二维数组的构建&#xff0c;如果用C语言动态构建二维数组是比较麻烦的&#xff0c;而用C中STL的vector<vector<int>>,就可以立马构建出来&#xff0c;这也…

本地生活服务平台都有哪些,靠谱吗?

随着本地生活服务的发展潜力和盈利方式被不断挖掘&#xff0c;越来越多的人开始发现其中所蕴含着的巨大商机&#xff0c;大家所熟悉的抖音、小红书和支付宝等平台也纷纷上线了本地生活板块&#xff0c;再次印证了其前景的广阔。在此背景下&#xff0c;普通人想要趁势入局分一杯…

前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。

1、思考 Vue的响应式到底要干什么&#xff1f; 无非就是要知道当你读取对象的时候&#xff0c;要知道它读了。要做一些别的事情无非就是要知道当你修改对象的时候&#xff0c;要知道它改了。要做一些别的事情所以要想一个办法&#xff0c;把读取和修改的动作变成一个函数&#…

Python语言在地球科学领域中的实践技术应用教程

原文链接&#xff1a;Python语言在地球科学领域中的实践技术应用教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601506&idx6&snee03d6abdbcbe0216a07340c1b49cb8d&chksmfa820c85cdf585934051f111b1d95877ba54e71cbe74be87f9e0bd07b8d46d97bbc7d…

深入理解大语言模型微调技术

一、概念解析 1、什么是微调&#xff08;Fine-tuning&#xff09;&#xff1f; 大模型微调&#xff0c;也称为Fine-tuning&#xff0c;是指在已经预训练好的大型语言模型基础上&#xff08;一般称为“基座模型”&#xff09;&#xff0c;使用特定的数据集进行进一步的训练&am…

基于Springboot的某大药房管理系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

小成本搏大流量:微信/支付宝小程序搜索排名优化

随着移动互联网的快速发展&#xff0c;小程序已成为企业和个人开发者重要的流量入口和业务承载平台。而小程序搜索排名则是影响小程序曝光量、用户获取及业务转化的关键因素。小柚在本文和大家探讨如何制定有效的优化方案&#xff0c;提升小程序在搜索结果中的排名。 首先跟我…

【图文教程】在PyCharm中导入Conda环境

文章目录 &#xff08;1&#xff09;在Anaconda Prompt中新建一个conda虚拟环境&#xff08;2&#xff09;使用PyCharm打开需要搭建环境的项目&#xff08;3&#xff09;配置环境 &#xff08;1&#xff09;在Anaconda Prompt中新建一个conda虚拟环境 conda create - myenv py…

Python SQL解析和转换库之sqlglot使用详解

概要 Python SQLGlot是一个基于Python的SQL解析和转换库,可以帮助开发者更加灵活地处理和操作SQL语句。本文将介绍SQLGlot库的安装、特性、基本功能、高级功能、实际应用场景等方面。 安装 安装SQLGlot库非常简单,可以使用pip命令进行安装: pip install sqlglot安装完成后…

Jenkins打包app并通过openssh上传到服务器

1、下载安装openssh 网上很多教程&#xff0c;包括开端口的&#xff0c;可以搜下 2、配置openssh根目录 进入C:\ProgramData\ssh打开文件sshd_config&#xff0c;添加配置ChrootDirectory D:\wxs\soft&#xff0c;想改端口的也在这个文件 3、安装Jenkins 参考上一篇 4、新…

WordPress采集插件大比拼:哪款才是站长的救星?

本着节约站长宝贵时间的理念&#xff0c;WordPress网站内容管理系统应采取自动化采集技术。因此催生了各种相应的WordPress提取插件和软件。然而&#xff0c;在众多可用选项面前&#xff0c;如何做出最佳选择成为关键问题。权衡的要素包括功能可靠性、易用性、稳定性以及定制程…

Java Bean 通用方法自动生成

原文&#xff1a;https://blog.iyatt.com/?p14637 使用 Lombok&#xff1a;https://mvnrepository.com/artifact/org.projectlombok/lombok 写了一个 Person 类&#xff0c;通过 Lombok 就可以生成通用的方法 package com.iyatt;import lombok.AllArgsConstructor; import l…

Linux系统中LVM与磁盘配额

目录 一、LVM逻辑卷管理 二、LVM的管理命令 物理卷管理 卷组管理 逻辑卷管理 *创建并使用LVM步骤 三、磁盘配额概述 实现磁盘限额的条件 Linux 磁盘限额的特点 四、磁盘配额管理 磁盘限额 一、LVM逻辑卷管理 能够在保持现有数据不变的情况下动态调整磁盘容量&#…

如何解决SSL证书不生效,有免费SSL证书吗?

SSL&#xff08;Secure Sockets Layer&#xff09;证书起着举足轻重的作用。它为网站提供加密服务&#xff0c;从而确保用户数据在传输过程中的安全性。然而&#xff0c;有时我们可能会遇到SSL证书不生效的问题&#xff0c;这不仅会降低网站的信任度&#xff0c;还可能导致数据…

支付宝支付之SpringBoot整合支付宝入门

支付宝支付 对接流程 申请阿里支付官方企业账号配置应用签约产品获取RSAKey&#xff08;非对称加密&#xff09;必须获得两个加密串&#xff1a;一个公钥&#xff0c;一个密钥SDK功能开发业务对接支付回调支付组件 核心所需的参数 APPID商家私钥支付宝公钥支付回调地址网关…

Python使用pymssql连接 SQLServer2008 报错:DB-Lib error message 20002, severity 9

Python使用pymssql连接 SQLServer2012没有问题&#xff0c;但是连接SQLServer2008就会报错DB-Lib error message 20002, severity 9&#xff0c;问题解决 可以打印详细连接过程的方式&#xff1a; import pymssql import os os.environ[TDSDUMP] stdout # 用于打印连接详细过…