美文网首页
模型方法二

模型方法二

作者: 程序员札记 | 来源:发表于2023-07-09 07:51 被阅读0次

createAttributeFromRequestValue

上篇说道,我们从请求参数里获得了属性值,但是是String类型的,而我们的参数需要是int的,所以这里会有一个绑定和转换的过程,我们来看看是怎么做的。

数据绑定器初始化

在创建数据绑定器WebDataBinder后,会进行初始化,也就是让数据绑定工厂的所有绑定方法来执行一遍,因为绑定方法那么多,不知道哪个是可以绑定上的,所以要遍历执行,先看能不能满足条件,满足条件的话就执行绑定方法,所以这里如果有很多的话,也不太会有太大的性能问题,因为可能只有一个能绑定上,甚至没有,只是会判断绑定的条件是否符合isBinderMethodApplicable

image.png

参数如何符合绑定方法呢

其实就是获取绑定方法上的InitBinder的注解属性值,其实就是参数ModelAttribute注解的属性名字符串数组,如果没有写名字,就是空字符串数组。如果InitBinder没写属性名,那就表示无条件符合,就会执行绑定方法,如果写了属性名,那会判断参数的属性名是否存在其中,存在才算满足。

image.png

遍历每一个属性名,进行比较,只要有满足的就可以了:


image.png

什么样的可以被无条件通过呢,就是一些全局的绑定方法,比如日期转换,好像这个方法老执行,是不是耗性能啊,其实不是,你看这个方法是有参数传进来的,是绑定到这个参数上,也就是数据绑定器上的:


image.png

数据转换

绑定器初始化完成后要进行数据的转换啦,先把属性值类型和参数类型封装成TypeDescriptor,然后判断是否可以转换,最后尝试转换。
[图片上传失败...(image-161df2-1688946087983)]

如何判断是否可转换

当然是尝试获得转换器啦:


image.png

getConverter

还是老套路,先缓存,然后遍历,找到后方缓存,没找到就放NoOpConverter对象,表示这个类型不能转换。

    @Nullable
    protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
        ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType);
        GenericConverter converter = this.converterCache.get(key);//缓存中取
        if (converter != null) {
            return (converter != NO_MATCH ? converter : null);
        }

        converter = this.converters.find(sourceType, targetType);//遍历所有的转换器取
        if (converter == null) {
            converter = getDefaultConverter(sourceType, targetType);
        }

        if (converter != null) {
            this.converterCache.put(key, converter);//放入缓存
            return converter;
        }

        this.converterCache.put(key, NO_MATCH);
        return null;
    }

GenericConversionService的find从所有转换器中寻找

具体他会获取两个类型的所有父类,依次封装成ConvertiblePair对象,然后进行转换器获取,因为转换器是个映射,键就是ConvertiblePair对象。这里按照层级归类的,先进行子类判断,最后再到父类。

@Nullable
        public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
            // Search the full type hierarchy
            List<Class<?>> sourceCandidates = getClassHierarchy(sourceType.getType());
            List<Class<?>> targetCandidates = getClassHierarchy(targetType.getType());
            for (Class<?> sourceCandidate : sourceCandidates) {
                for (Class<?> targetCandidate : targetCandidates) {
                    ConvertiblePair convertiblePair = new ConvertiblePair(sourceCandidate, targetCandidate);
                    GenericConverter converter = getRegisteredConverter(sourceType, targetType, convertiblePair);
                    if (converter != null) {
                        return converter;
                    }
                }
            }
            return null;
        }

getRegisteredConverter

关键就是这里啦,converters是初始化的时候就创建的,而且把转换器都放进去了,是个Map<ConvertiblePair, ConvertersForPair>映射。所以知道为什么前面要封装成ConvertersForPair对象了吧,为了这里快速获取。获取ConvertersForPair之后在从里面获取对应的转换器,如果获取不到就从全局里获取。

image.png

转换器找到了,我们下篇说说怎么转换吧。

相关文章

  • Tensorflow 训练好的模型保存和载入

    方法一 这种存储方式在加载模型时需要再次定义网络结构 模型训练和存储 加载模型 方法二 这种存储方式在加载模型...

  • TensorFlow笔记(一)

    一:变量管理 二:模型持久化方法1.保存模型 2.加载已保存的模型

  • SpringMVC工作流程

    处理模型数据方式一:将方法返回值设置为MOdelAndView 处理模型数据方式二:方法返回值仍然是string类...

  • Django模型

    一、Objects管理器 自定义object管理器 二、模型类 添加类方法【快速创建模型对象】 添加对象方法【快速...

  • JVM内存模型

    一、jvm内存模型图 二、内存模型描述 堆:所有新建对象都会在堆中开辟内存 方法区(本地内存):存放类信息,方法信...

  • HashMap源码分析

    目录 一、数据模型 二、重要属性 三、构造方法 四、普通方法 put() resize() get() 五、总结 ...

  • 模型效果上限预估、分类模型Bad Case分析方法

    模型效果上限预估、分类模型Bad Case分析方法 给定训练和测试数据集,训练某个二分类模型(如,GBDT算法),...

  • CNN模型加速之量化模型

    引言 量化模型是一种模型加速方法的总称,其中包括:二值化网络、三值化网络和深度压缩等。 二值化网络 在构建模型时使...

  • Spring 中jdbcTemplate用法

    方法一:appplication-context文件配置 模型层省略(一个user)。。。dao层; 方法二: 控制层:

  • django数据操作总结

    模型: 一、往表中插入数据 方法一obj = Author(name='曹雪芹')obj.save() 方法二 o...

网友评论

      本文标题:模型方法二

      本文链接:https://www.haomeiwen.com/subject/mitsudtx.html