范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringCloud升级之路2020。0。x版29。SCOpenFeign的解析(2)

  本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent
  在使用云原生的很多微服务中,比较小规模的可能直接依靠云服务中的负载均衡器进行内部域名与服务映射,通过健康检查接口判断实例健康状态,然后直接使用 OpenFeign 生成对应域名的 Feign Client。Spring Cloud 生态中,对 OpenFeign 进行了封装,其中的 Feign Client 的各个组件,也是做了一定的定制化,可以实现在 OpenFeign Client 中集成服务发现与负载均衡。在此基础上,我们还结合了 Resilience4J 组件,实现了微服务实例级别的线程隔离,微服务方法级别的断路器以及重试。
  我们先来分析下 Spring Cloud OpenFeign Spring Cloud OpenFeign 解析HTTP 编码解码器,与 spring-boot 中的编码解码器相结合
  Spring Cloud 中的任何组件,都是基于 Spring Boot 而实现的。由于 Spring Boot 中已经有了 HTTP 编码解码器,就可以不用单独给 OpenFeign 单独再实现 HTTP 编码解码器了,而是考虑将 OpenFeign 的编码解码器接口用 Spring Boot 的 HTTP 编码解码器实现。
  在 FeignClientsConfiguration 中,提供了默认的实现: //由于初始化顺序以及 NamedContextFactory 的 Configuration 初始化的原因,这里需要注入 ObjectFactory 而不是直接注入 HttpMessageConverters 防止找不到 Bean @Autowired private ObjectFactory messageConverters;  @Bean @ConditionalOnMissingBean public Decoder feignDecoder() {  	return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(this.messageConverters))); }  @Bean @ConditionalOnMissingBean //我们这里忽略 Pageable 类存在的情况 //针对 Spring Data 的分页包装 Pageable 的兼容实现也比较简单,这里忽略 @ConditionalOnMissingClass("org.springframework.data.domain.Pageable") public Encoder feignEncoder(ObjectProvider formWriterProvider) { 	return springEncoder(formWriterProvider, encoderProperties); }  private Encoder springEncoder(ObjectProvider formWriterProvider, 	FeignEncoderProperties encoderProperties) {     AbstractFormWriter formWriter = formWriterProvider.getIfAvailable();          if (formWriter != null) {     	return new SpringEncoder(new SpringPojoFormEncoder(formWriter), this.messageConverters, encoderProperties);     }     else {     	return new SpringEncoder(new SpringFormEncoder(), this.messageConverters, encoderProperties);     } } 基于 SpringDecoder 的解码器
  通过源码可以看出,默认的 Decoder 是经过几层包装的 Decoder,分别包括: OptionalDecoder :用于处理 Java JDK 中的 Optional 封装类的解码器 ResponseEntityDecoder :用于处理 spring-web 中对于请求响应封装类 HttpEntity 的解码器 SpringDecoder :使用 Spring 的解码器实现的 Feign 的 Decoder
  传入 SpringDecoder 的 HttpMessageConverters 对象,是 spring-web 的所有 HttpMessageConverter 集合。HttpMessageConverter 是 spring-web 中对于 HTTP 请求和响应的 body 进行编码解码的工具。其接口结构是: public interface HttpMessageConverter {     //判断 clazz 类型是否可以被当前 HttpMessageConverter 所读取 	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);     //判断 clazz 类型是否可以被当前 HttpMessageConverter 写 	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);     //获取所有支持的 MediaType 	List getSupportedMediaTypes();     //通过 clazz 类型获取该 HttpMessageConverter 支持的 MediaType     //默认实现是,如果该类型可以被当前 HttpMessageConverter 读或者写,那么返回 getSupportedMediaTypes 所有支持的 MediaType 	default List getSupportedMediaTypes(Class<?> clazz) { 		return (canRead(clazz, null) || canWrite(clazz, null) ? 				getSupportedMediaTypes() : Collections.emptyList()); 	}      //从 inputMessage 中读取并解析出 clazz 类型的对象,当请求的 Content-Type 为支持的 MediaType 时 	T read(Class<? extends T> clazz, HttpInputMessage inputMessage) 			throws IOException, HttpMessageNotReadableException;      //将对象 t 序列化写入 HttpOutputMessage,当请求的 accept 为支持的 MediaType 时 	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) 			throws IOException, HttpMessageNotWritableException;  }
  spring boot 内置了很多 HttpMessageConverter,我们也可以实现自己的 HttpMessageConverter,去实现我们自定义 MediaType,例如我们这里定义一个 : public class CustomizedHttpMessageConverter implements HttpMessageConverter { 	@Override 	public boolean canRead(Class<?> clazz, MediaType mediaType) { 		return clazz.equals(Student.class); 	}  	@Override 	public boolean canWrite(Class<?> clazz, MediaType mediaType) { 		return clazz.equals(Student.class); 	} 	 	public static class StudentMediaType extends MediaType { 		public StudentMediaType() { 			super("application", "student", StandardCharsets.UTF_8); 		} 	}  	@Override 	public List getSupportedMediaTypes() { 		return List.of(new StudentMediaType()); 	}  	@Override 	public Student read(Class<? extends Student> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { 		String temp = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8); 		String[] split = temp.split(","); 		return new Student( 				Long.parseLong(split[0]), 				split[1]); 	}  	@Override 	public void write(Student student, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { 		outputMessage.getBody().write((student.getId() + "," + student.getName()).getBytes(StandardCharsets.UTF_8)); 	} }
  之后,与前面类似,将其配置到 spring boot 兼容 MVC 配置中: @Configuration(proxyBeanMethods = false) public class TestConfig implements WebMvcConfigurer { 	@Override 	public void extendMessageConverters(List> converters) { 		converters.add(new CustomizedHttpMessageConverter()); 	} }
  编写 Controller,测试: @RestController @RequestMapping("/test") public class TestController { 	@PostMapping("/post-to-student") 	public Student postToStudent(@RequestBody Student student) { 		return student; 	} }
  使用 postman 类似的工具,指定 HTTP 请求头: Content-Type:application/student Accept:application/student
  Body 是: 1,zhx
  请求后,就会走到 CustomizedHttpMessageConverter 的 read 解析成 Student 对象,之后响应的 student 也会被 CustomizedHttpMessageConverter 的 write 写入响应 Body
  由此可见, 由于 SpringEncoder 的存在,我们可以复用 Spring 内置的 HttpMessageConverter,同时也能扩展自定义我们自己的 HttpMessageConverter,非常方便 。
  ResponseEntityDecoder 的代码比较简单,实现的效果就是解码的时候,忽略 HttpEntity 这个 spring-web 对于 HTTP 响应的包装类: @Override public Object decode(final Response response, Type type) throws IOException, FeignException {     //是否是带有形参的 HttpEntity<?>  	if (isParameterizeHttpEntity(type)) { 	    //将形参类型取出 		type = ((ParameterizedType) type).getActualTypeArguments()[0]; 		//使用形参类型,解析 response 		Object decodedObject = this.decoder.decode(response, type);         //填充 HttpEntity 其中的返回对象,状态码等信息 		return createResponse(decodedObject, response); 	} 	else if (isHttpEntity(type)) { 	    //空形参,代表没有 body 或者忽略 body,仅填充 HttpEntity 状态码等信息 		return createResponse(null, response); 	} 	else { 	    //如果不是 HttpEntity,直接解码 		return this.decoder.decode(response, type); 	} }
  这个其实为了和 RestTemplate 的响应兼容,RestTemplate 可以返回 HttpEntity,但是底层 HTTP 请求返回的 body 其实并没有包装这个类型。
  同理,JDK 中的 Optional 包装类,也需要做同样的事情,这个就是通过 OptionalDecoder 实现的。 基于 SpringEncoder 的编码器
  SpringEncoder 编码器也非常简单,也是基于 spring 中的 HttpMessageConverter。这里我们就不再赘述。

中国邮政快递业稳居全球第一建制村全部直接通邮让邮路覆盖全国,让快递下乡进村,让每一个家庭都能享受优质的寄递服务。党的十八大以来,我国抓重点补短板强弱项,建成了与全面小康相适应的现代邮政快递业。行业收入规模由2012年的1982030年有望面世的八种超级技术和发明一石墨烯石墨烯是石墨的副产品,而石墨本身就是碳的近亲。该产品非常坚固,但又非常薄轻有弹性(比钢更坚固,比纸更薄)它的导电性能也非常好。其应用非常多,特别是在可穿戴电子设备和太空旅行到2025年将改变全球经济的10项顶流技术1大数据据预测,到2025年,世界上的数据将增长到175兆字节。大数据对商业来说是无价之宝。我们不仅可以从每时每刻产生的数据中得出重大结论,而且我们现在还有机器学习,可以加速分析和Google向法庭申请要求其长期批评人士之一LutherLowe提供文件据外媒TheVerge报道,当地时间周一晚间,Google申请法庭命令,要求Google垄断搜索市场的长期批评人士之一LutherLowe提供文件,作为其正在进行的联邦反垄断案(U经常看到9元月租卡,说的天花乱坠,移动电信都有,有用过的吗?有用过还行我用过19的,现在也在用,也是有套路,激活以后马上暗箱操作套路了一个月39,这样一个月固定消费58了,然后继续套路时候被我发现了一顿臭骂,因为了解一些运营商内部的一些制度平凡的故事最近,教育部的双减政策得到了社会广泛的关注。K12教育领域正在承受着前所未有的巨大变革。作为头部互联网k12教育机构的一名招生顾问,我也是第一时间得到了消息。一开始总部打算根据校区在当今这个社会什么行业比较有前景?高尖端科技项目,但一般的人又参于不了,限于知识水平呲牙呲牙呲牙谢邀高科技芯片等,智能高科技产品,新能源公司,5G网络产品,基础设施建设,军工,等会有比较好的前景。欢迎指点补充玫瑰玫不用种地了?我国科学家用二氧化碳合成淀粉,效率是玉米的8。5倍淀粉是小麦玉米等作物的主要成分,也是工业上的原料。传统上,生产淀粉主要靠农业种植。农作物从空气中捕获二氧化碳,并通过光合作用生成淀粉。但是,这个过程效率非常低下,仅有2的太阳能转化国庆专题新能源汽车销量井喷喜人,但出行仍无法消除充电尴尬金九银十是农业收获季节,也是消费火热的黄金时间点。金九银十的说法不只出现手机家电行业,汽车行业同样也如此。随着绿色环保政策的不断调整,新能源车作为近几年的大热消费品,这块市场蛋糕已亚马逊CEO视频游戏可能成为最大的娱乐业务亚马逊CEO安迪贾西(AndyJassy)周二在一次科技大会上表示,从长远来看,视频游戏最终可能成为最大的娱乐类别。亚马逊长期以来一直在努力制作一款优秀的视频游戏。一周前,该公司发谷歌的安卓系统在中国免费使用,那他在这过程中有什么利益或者收入?应邀回答本行业问题。谷歌的安卓系统,目前在全球都是免费使用的,他的主要利润在于搭载一系列的谷歌应用,不过这个好处在中国是没有的。谷歌的安卓系统,其实是可以收费的,不过在国内它也收不
2K屏加5G网络!华为Mate50将于年底发布华为手机在今年的表现可以说是一波多折,其发布的华为P50系列无法支持5G网络功能,这也使得其销量有所下降。但为了弥补这一缺憾,华为计划在今年稍晚时发布全新的华为Mate50系列,这谷歌安卓上新功能用脸就能控制手机智东西(公众号zhidxcom)编译杨畅编辑Panken智东西8月18日消息,据外媒报道,谷歌最近更新了其安卓无障碍(辅助功能)套件(AndroidAccessibilitySui独家他加入神童李一男的公司后被并到华为却靠极米创造神话运营商财经实习生李思缘文近日,极米科技携手保时捷设计共同推出极米RSAIR保时捷设计智能投影。纵观整个投影仪市场,极米科技在产品数量质量和品种方面,都已逐步走向成熟。作为行业领军企不用再担心手机空间小了!aigo国民好物固态U盘U393刷新你的认知在移动互联网高速发展的时代,我们使用手机的频率也越来越高,甚至有些人手机不离身,因此,这也导致了我们手机里的东西越来越多,即便是手机厂商不断扩展内存,从原先的8G16G32G升级到一起事故,蔚来从众人追捧到今日说法Q2财报发布之后,蔚来本应凭借财报再度成为业界关于新能源市场分析的重要案例之一,但近期的两起事故让刚发酵起来的蔚来前途话题迅速沉寂,甚至转变成了今日说法使用自动驾驶时如果发生事故,今日热点曝大批骁龙898旗舰!小米12首发科技行业新鲜趣事一文速览,在这里你可以了解科技热点获悉行业动态,话不多说让我们一起来看看吧曝大批骁龙898旗舰小米12首发日前,4nm工艺的高通骁龙898曝光了,有消息称目前有一大100公里路程消耗续航也是100吗?高德新能源导航推出续航预估算法电动汽车跑100公里需要有多少续航才安心?开到目的地预计要掉多少电?跑高速和走省道哪条路耗电更少?针对新能源车主的痛点需求,高德地图新能源导航快速迭代更新,近日创新推出了续航预估智适老化版APP受热捧,并非年轻人老了文严奇想不到,我一个90后能把老年模式用得这么香。记者采访发现,不少适老版APP在成功被老年群体接受之前,却率先收获了一批年轻粉丝。随着APP适老化逐渐推进,页面简洁操作简单的适老第11天鸿蒙App开发实战,相对布局相对布局DependentLayout,也是比较常用的一个布局管理器,在它里面,组件的排列方式是相对于其他同级组件或者父组件的位置进行布局。相对同级组件组件B神,想躲在组件A卡的后即将来袭的苹果13到底如何?刚刚看了一条消息,万众期待的iPhone13预计可能在今年的秋季9月14上线,这让我们这些错过了12的小伙伴有了一些期待,毕竟我还是一个听劝的人,身边的朋友都告诉我十三香的告诫,那京东旗舰店和自营店的区别,哪一个更好?现在网络购物的环境越来越好了,以前从不网购的小伙伴也纷纷开始网购。京东商城相对来说是大家使用比较多的一个购物软件,但是即便是在同一个平台购物,不同的店铺商品质量也不会一样。今天Pi