-
找到目标参数
-
检查是否需要特殊转换逻辑
-
如果需要,进行转换
-
如果不需要,直接返回
获取输入参数的逻辑在org.springframework.web.method.annotation.RequestParamMethodArgumentResolver#resolveName
,单参数返回的是 String 类型,多参数返回 String 数组。核心代码如下:
所以说,无论我们的目标参数是什么,输入参数都是 String 类型或 String 数组,然后 Spring 把它们转换为我们期望的类型。
找到目标参数的逻辑在DispatcherServlet
中,根据 uri 找到对应的 Controller 处理方法,找到方法就找到了目标参数类型。
接下来就是检查是否需要转换逻辑,也就是org.springframework.validation.DataBinder#convertIfNecessary
,顾名思义,如果需要就转换,将字符串类型转换为目标类型。在我们的例子中,就是将 String 转换为枚举值。
查找转换器
继续深扒,会在org.springframework.beans.TypeConverterDelegate#convertIfNecessary
方法中找到这么一段逻辑:
这段逻辑中,调用了org.springframework.core.convert.support.GenericConversionService#canConvert
方法,检查是否可转换,如果可以转换,将会执行类型转换逻辑。
检查是否可转换的本质就是检查是否能够找到对应的转换器。如果能找到,就用找到的转换器开始转换逻辑,如果找不到,那就是不能转换,走其他逻辑。
我们可以看看查找转换器的代码org.springframework.core.convert.support.GenericConversionService#getConverter
,可以对我们自己写代码有一些启发:
转换为伪代码就是:
-
根据参数类型和目标类型,构造缓存 key
-
根据缓存 key,从缓存中查询转换器
-
如果能找到且不是 NO_MATCH,返回转换器;如果是 NO_MATCH,返回 null;如果未找到,继续
-
通过org.springframework.core.convert.support.GenericConversionService.Converters#find查询转换器
-
如果未找到,检查源类型和目标类型是否可以强转,也就是类型一致。如果是,返回 NoOpConverter,如果否,返回 null。
-
检查找到的转换器是否为 null,如果不是,将转换器加入到缓存中,返回该转换器
-
如果否,在缓存中添加 NO_MATCH 标识,返回 null
Spring 内部使用Map
作为缓存,用来存储通用转换器接口GenericConverter
,这个接口会是我们自定义转换器的包装类。我们还可以看到,转换器缓存用的是ConcurrentReferenceHashMap
,这个类是线程安全的,可以保证并发情况下,不会出现异常存储。但是getConverter
方法没有使用同步逻辑。换句话说,并发请求时,可能存在性能损耗。不过,对于 web 请求场景,并发损耗好过阻塞等待。
我们在看下 Spring 是如何查找转换器的,在org.springframework.core.convert.support.GenericConversionService.Converters#find
中就是找到对应转换器的核心逻辑:
我们可以看到,Spring 是通过源类型和目标类型组合起来,查找对应的转换器。而且,Spring 还通过getClassHierarchy
方法,将源类型和目标类型的家族族谱全部列出来,用双层 for 循环遍历查找。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。
注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友
互联网工程师必备的面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题**。
[外链图片转存中…(img-ecNtzkFF-1711005937665)]