布丰投针实验原理、仿真过程以及 MATLAB仿真代码、完整的布丰投针实验报告。

以下内容无关:

-------------------------------------------分割线---------------------------------------------

本文的焦点将集中在上文留下的4个类型转换器上。

StreamConverter:将Stream流与集合/数组之间的转换,必要时转换元素类型

这三个比较特殊,属于“最后的”“兜底类”类型转换器:

ObjectToObjectConverter:通用的将原对象转换为目标对象(通过工厂方法or构造器)

IdToEntityConverter:本文重点。给个ID自动帮你兑换成一个Entity对象

FallbackObjectToStringConverter:将任何对象调用toString()转化为String类型。当匹配不到任何转换器时,它用于兜底

默认转换器注册情况

Spring新一代类型转换内建了非常多的实现,这些在初始化阶段大都被默认注册进去。注册点在DefaultConversionService提供的一个static静态工具方法里:

static静态方法具有与实例无关性,我个人觉得把该static方法放在一个xxxUtils里统一管理会更好,放在具体某个组件类里反倒容易产生语义上的误导性

public static void addDefaultConverters(ConverterRegistry converterRegistry) {

// 1、添加标量转换器(和数字相关)

addScalarConverters(converterRegistry);

// 2、添加处理集合的转换器

addCollectionConverters(converterRegistry);

// 3、添加对JSR310时间类型支持的转换器

converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));

converterRegistry.addConverter(new StringToTimeZoneConverter());

converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());

converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

// 4、添加兜底转换器(上面处理不了的全交给这几个哥们处理)

converterRegistry.addConverter(new ObjectToObjectConverter());

converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));

converterRegistry.addConverter(new FallbackObjectToStringConverter());

converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));

}

}

该静态方法用于注册全局的、默认的转换器们,从而让Spring有了基础的转换能力,进而完成绝大部分转换工作。为了方便记忆这个注册流程,我把它绘制成图供以你保存:

特别强调:转换器的注册顺序非常重要,这决定了通用转换器的匹配结果(谁在前,优先匹配谁)。

针对这幅图,你可能还会有疑问:

JSR310转换器只看到TimeZone、ZoneId等转换,怎么没看见更为常用的LocalDate、LocalDateTime等这些类型转换呢?难道Spring默认是不支持的?

答:当然不是。 这么常见的场景Spring怎能会不支持呢?不过与其说这是类型转换,倒不如说是格式化更合适。所以会在后3篇文章格式化章节在作为重中之重讲述

一般的Converter都见名之意,但StreamConverter有何作用呢?什么场景下会生效

答:本文讲述

对于兜底的转换器,有何含义?这种极具通用性的转换器作用为何

答:本文讲述

StreamConverter

用于实现集合/数组类型到Stream类型的互转,这从它支持的Set 集合也能看出来:

@Override

public Set getConvertibleTypes() {

Set convertiblePairs = new HashSet();

convertiblePairs.add(new ConvertiblePair(Stream.class, Collection.class));

convertiblePairs.add(new ConvertiblePair(Stream.class, Object[].class));

convertiblePairs.add(new ConvertiblePair(Collection.class, Stream.class));

convertiblePairs.add(new ConvertiblePair(Object[].class, Stream.class));

return convertiblePairs;

}

它支持的是双向的匹配规则:

代码示例{@link StreamConverter}

*/

@Test

public void test2() {

System.out.println("----------------StreamConverter---------------");

ConditionalGenericConverter converter = new StreamConverter(new DefaultConversionService());

TypeDescriptor sourceTypeDesp = TypeDescriptor.valueOf(Set.class);

TypeDescriptor targetTypeDesp = TypeDescriptor.valueOf(Stream.class);

boolean matches = converter.matches(sourceTypeDesp, targetTypeDesp);

System.out.println(“是否能够转换:” + matches);

// 执行转换

Object convert = converter.convert(Collections.singleton(1), sourceTypeDesp, targetTypeDesp);

System.out.println(convert);

System.out.println(Stream.class.isAssignableFrom(convert.getClass()));

}

运行程序,输出:

1

2

3

4

----------------StreamConverter---------------

是否能够转换:true

java.util.stream.ReferencePipeline$Head@5a01ccaa

true

关注点:底层依旧依赖DefaultConversionService完成元素与元素之间的转换。譬如本例Set -> Stream的实际步骤为:

也就是说任何集合/数组类型是先转换为中间状态的List,最终调用list.stream()转换为Stream流的;若是逆向转换先调用source.collect(Collectors.toList())把Stream转为List后,再转为具体的集合or数组类型。

说明:若source是数组类型,那底层实际使用的就是ArrayToCollectionConverter,注意举一反三

使用场景

StreamConverter它的访问权限是default,我们并不能直接使用到它。通过上面介绍可知Spring默认把它注册进了注册中心里,因此面向使用者我们直接使用转换服务接口ConversionService便可。

1

2

3

4

5

6

7

8

9

10

@Test

public void test3() {

System.out.println("----------------StreamConverter使用场景---------------");

ConversionService conversionService = new DefaultConversionService();

Stream result = conversionService.convert(Collections.singleton(1), Stream.class);

// 消费

result.forEach(System.out::println);

// result.forEach(System.out::println); //stream has already been operated upon or closed

}

运行程序,输出:

1

2

----------------StreamConverter使用场景---------------

1

再次特别强调:流只能被读(消费)一次。

因为有了ConversionService提供的强大能力,我们就可以在基于Spring/Spring Boot做二次开发时使用它,提高系统的通用性和容错性。如:当方法入参是Stream类型时,你既可以传入Stream类型,也可以是Collection类型、数组类型,是不是瞬间逼格高了起来。

兜底转换器

按照添加转换器的顺序,Spring在最后添加了4个通用的转换器用于兜底,你可能平时并不关注它,但它实时就在发挥着它的作用。

ObjectToObjectConverter

将源对象转换为目标类型,非常的通用:Object -> Object:

1

2

3

4

@Override

public Set getConvertibleTypes() {

return Collections.singleton(new ConvertiblePair(Object.class, Object.class));

}

虽然它支持的是Object -> Object,看似没有限制但其实是有约定条件的:

1

2

3

4

5

@Override

public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {

return (sourceType.getType() != targetType.getType() &&

hasConversionMethodOrConstructor(targetType.getType(), sourceType.getType()));

}

是否能够处理的判断逻辑在于hasConversionMethodOrConstructor方法,直译为:是否有转换方法或者构造器。代码详细处理逻辑如下截图:

此部分逻辑可分为两个part来看:

part1:从缓存中拿到Member,直接判断Member的可用性,可用的话迅速返回

part2:若part1没有返回,就执行三部曲,尝试找到一个合适的Member,然后放进缓存内(若没有就返回null)

part1:快速返回流程

当不是首次进入处理时,会走快速返回流程。也就是第0步isApplicable判断逻辑,有这几个关注点:

Member包括Method或者Constructor

Method:若是static静态方法,要求方法的第1个入参类型必须是源类型sourceType;若不是static方法,则要求源类型sourceType必须是method.getDeclaringClass()的子类型/相同类型

Constructor:要求构造器的第1个入参类型必须是源类型sourceType

创建目标对象的实例,此转换器支持两种方式:

通过工厂方法/实例方法创建实例(method.invoke(source))

通过构造器创建实例(ctor.newInstance(source))

以上case,在下面均会给出代码示例。

part2:三部曲流程

对于首次处理的转换,就会进入到详细的三部曲逻辑:通过反射尝试找到合适的Member用于创建目标实例,也就是上图的1、2、3步。

step1:determineToMethod,从sourceClass里找实例方法,对方法有如下要求:

方法名必须叫"to" + targetClass.getSimpleName(),如toPerson()

方法的访问权限必须是public

该方法的返回值必须是目标类型或其子类型

step2:determineFactoryMethod,找静态工厂方法,对方法有如下要求:

方法名必须为valueOf(sourceClass) 或者 of(sourceClass) 或者from(sourceClass)

方法的访问权限必须是public

step3:determineFactoryConstructor,找构造器,对构造器有如下要求:

存在一个参数,且参数类型是sourceClass类型的构造器

构造器的访问权限必须是public

特别值得注意的是:此转换器不支持Object.toString()方法将sourceType转换为java.lang.String。对于toString()支持,请使用下面介绍的更为兜底的FallbackObjectToStringConverter。

蒲丰投针实验原理_布丰投针实验 MATLAB仿真 以及报告相关推荐

  1. 万丰科技机器人排名_万丰科技拟“借壳”长春经开

    继ST亚星重组济南"老字号"宏济堂拿下2020年借壳第一单之后,2020年借壳第二单有望花落长春经开. 长春经开1月15日晚间披露重大资产重组预案,拟以发行股份及支付现金的方式,向 ...

  2. 苹果手机投屏软件_苹果手机怎样投屏到电脑上操作,用什么软件?

    金舟苹果手机投屏软件是一款专业的苹果手机投屏软件,支持苹果手机投屏至Windows系统,支持投屏录制.全屏投屏.截屏.白板等功能,全方位解决您的问题! 功能介绍 1.旋转 无需手机操作,软件界面也是可 ...

  3. 顺丰java面试题_顺丰java开发面试分享,顺丰java面试经面试题

    今天要给大家分享的是一个小伙伴的顺丰java开发面试过程,其中包括了面试流程,面试题目,和回答,感兴趣的朋友可以来了解一下哈. 一.面试流程 是中午进行的面试,首先是做自我介绍,之后就是讲一下项目,然 ...

  4. 苹果手机投屏软件_苹果手机怎么投屏到电脑上?支你一招

    苹果手机一次次升级都会给我们带来不一样的体验感,airplay投屏便是苹果手机系统中很好的一大特色,有了它你就可以轻松把手机文档投电脑,电脑投屏电视,手机视频.手机音乐投屏到电脑等等. 比如说工作中我 ...

  5. 安卓手机投屏软件_手机车载投屏的方法安卓、苹果都支持

    昨天有用户咨询说他想手机投屏到他的车载显示屏上,经过一番探讨,最后咨询那哥们终于用MHL线进行手机屏幕和车载屏幕连接成功了.事后小编采集了一些手机投屏到车载显示屏上的方法,希望对大家有用. 解决方案一 ...

  6. 安卓手机投屏软件_安卓手机投屏竟然这么简单,每个安卓手机都可以!

    很多人问到安卓系统的手机怎么投屏的问题,因为除了一些新款手机.以前的老版安卓手机很多是不自带投屏功能的,那么对于以前的老版安卓手机而言,怎么做到投屏呢?其实这个问题非常容易解决,不多说,我们来看下解决 ...

  7. 蒸发器分段设计matlab程序_制冷系统蒸发器过热度控制回路的MATLAB仿真_何煜

    . 王志刚 710049 陕西西安市西安交通大学能源与动力学院 制冷系统蒸发器过热度控制回路的 M A T LAB 仿真 上海交通大学 何 煜 仲 华 唐双波 陈芝久 摘 要 根据 实际制冷 系统的电 ...

  8. saber仿真软件_电力电子应用技术的MATLAB仿真

    欢迎加入技术交流QQ群(2000人):电力电子技术与新能源 905723370 高可靠新能源行业顶尖自媒体 在这里有电力电子.新能源干货.行业发展趋势分析.最新产品介绍.众多技术达人与您分享经验,欢迎 ...

  9. R语言对布丰投针(蒲丰投针)实验进行模拟和动态可视化生成GIF动画

    最近我们被客户要求撰写关于动态可视化的研究报告,包括一些图形和统计输出. 介绍 布丰投针是几何概率领域中最古老的问题之一.它最早是在1777年提出的.它将针头掷到有平行线的纸上,并确定针和其中一条平行 ...

最新文章

  1. 松江库卡机器人_上海高质量发展调研行|库卡机器人:为全球提供“松江创造”的产品...
  2. Java线程池详解学习:ThreadPoolExecutor
  3. java绘制地球绕太阳转_Unity3D 公转小案例:地球围绕太阳转
  4. CentOS6.7安装jdk1.8
  5. MaxCompute 实现增量数据推送(全量比对增量逻辑)
  6. 8.String、StringBuffer、enum枚举
  7. 问题2----网速问题?造成的ORA-01034和ORA-27101
  8. (转)拿到软银44亿美金巨资后,WeWork要这样布局中国市场
  9. 禁止百度云盘p2p后台上传
  10. eclipse导入html页面乱码,Eclipse导入项目乱码问题(中文乱码)
  11. Android Wi-Fi源码分析之wpa_supplicant初始化(三):wpa_supplicant_add_iface函数分析
  12. 数据分析师笔试题(一)
  13. c语言中偶数的平方while,在C语言中可以用以下语句来实现循环:1. 用while语句;2. ...新版1127.ppt...
  14. 魅族flashfire_魅族Pro6s更新安卓7.1后完美root及xp框架
  15. 概率论基础 - 7 - 特征函数
  16. camera模组 ------- super Good
  17. 车载摄像头在ADAS中的应用
  18. ffmpeg命令分析-t
  19. 五年级计算机教案上册,五年级上册信息技术教案【三篇】
  20. 学习C#必备的编程软件——pow_na的博客

热门文章

  1. 私有云、公有云还是混合云?
  2. 2021年07月虹科Pico汽车示波器简报
  3. visual studio性能探查器
  4. 传说中Google AdWords黄金账户的标准
  5. python:pyecharts地图功能,并解决显示不全或只显示南海诸岛问题解决,其实很简单
  6. ftrace--------------trace points
  7. 渗透测试工具—xray
  8. 航空公司客户价值分析(附完整代码)
  9. 2023年新课标I卷作文,5位人工智能考生(ChatGPT,文心一言,GPT4, ChatGLM-6b, ChatT5)来写作,看谁写得最好
  10. 安科瑞交直流充电桩用电计量方案-Susie 周