当前位置: 首页 > news >正文

做网站推广价格物流公司网站制作模板

做网站推广价格,物流公司网站制作模板,郑州注册公司需要多少钱,wordpress自媒体博客主题FeignClient介绍 FeignClient 是 Spring Cloud 中用于声明一个 Feign 客户端的注解。由于SpringCloud采用分布式微服务架构#xff0c;难免在各个子模块下存在模块方法互相调用的情况。比如订单服务要调用库存服务的方法#xff0c;FeignClient()注解就是为了解决这个问题的…FeignClient介绍 FeignClient 是 Spring Cloud 中用于声明一个 Feign 客户端的注解。由于SpringCloud采用分布式微服务架构难免在各个子模块下存在模块方法互相调用的情况。比如订单服务要调用库存服务的方法FeignClient()注解就是为了解决这个问题的。 Feign 是一个声明式的 Web Service 客户端它的目的是让编写 HTTP 客户端变得更简单。通过 Feign只需要创建一个接口并使用注解来描述请求就可以直接执行 HTTP 请求了。 FeignClient()注解的源码要求它必须在Interface接口上使用 FeignClient注解被Target(ElementType.TYPE)修饰表示FeignClient注解的作用目标在接口上 SpringBoot服务的启动类必须要有EnableFeignClients 注解才能使FeginClient注解生效。 FeignClient工作原理及整体流程 Feign服务调用的工作原理可以总结为以下几个步骤 首先通过EnableFeignCleints注解开启FeignCleint。根据Feign的规则实现接口添加FeignCleint注解。程序启动后会扫描所有有FeignCleint的类并将这些信息注入到ioc容器中。注入时从FeignClientFactoryBean.class获取FeignClient。当接口的方法被调用时通过jdk的代理来生成具体的RequesTemplateRequesTemplate生成http的Request。Request交给Client去处理其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp。Client被封装到LoadBalanceClient类这个类结合类Ribbon做到了负载均衡。 整体流程 FeignClient常用属性 name、value 指定FeignClient的名称如果项目使用了Ribbonname属性会作为微服务的名称用于服务发现 这两个属性的作用是一样的如果没有配置url那么配置的值将作为服务的名称用于服务的发现反之只是一个名称。 FeignClient(name order-server) public interface OrderRemoteClient {GetMapping(/order/detail)public Order detail(RequestParam(orderId) String orderId); }注意 这里写的是你要调用的那个服务的名称spring.application.name属性配置而不是你自己的那个服务的名称。如果同一个工程中出现两个接口使用一样的服务名称会报错。原因是Client名字注册到容器中重复了。除非指定不同的contextId参数。 Description: The bean ‘order-server.FeignClientSpecification’, defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled. Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overridingtrue 两种解决方案 增加配置 spring.main.allow-bean-definition-overridingtrue为每个FeignClient手动指定不同的contextId contextId 比如我们有个user服务但user服务中有很多个接口我们不想将所有的调用接口都定义在一个类中那就可以给不同的client指定contextId不然就会报Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overridingtrue异常。 注意contextId不能带_等符号。 FeignClient(name order-server) public interface OrderRemoteClient {GetMapping(/api/order/detail, contextId OrderRemoteClient)public Order detail(RequestParam(orderId) String orderId); }上面给出了Bean名称冲突后的解决方案下面来分析下contextId在Feign Client的作用在注册Feign Client Configuration的时候需要一个名称名称是通过getClientName方法获取的 String name getClientName(attributes);registerClientConfiguration(registry, name, attributes.get(configuration));private String getClientName(MapString, Object client) {if (client null) {return null;}String value (String) client.get(contextId);if (!StringUtils.hasText(value)) {value (String) client.get(value);}if (!StringUtils.hasText(value)) {value (String) client.get(name);}if (!StringUtils.hasText(value)) {value (String) client.get(serviceId);}if (StringUtils.hasText(value)) {return value;}throw new IllegalStateException(Either name or value must be provided in FeignClient.class.getSimpleName());}可以看到如果配置了contextId就会用contextId如果没有配置就会去value然后是name最后是serviceId。默认都没有配置当出现一个服务有多个Feign Client的时候就会报错了。 其次的作用是在注册FeignClient中contextId会作为Client 别名的一部分如果配置了qualifier优先用qualifier作为别名。 private void registerFeignClient(BeanDefinitionRegistry registry,AnnotationMetadata annotationMetadata, MapString, Object attributes) {String className annotationMetadata.getClassName();BeanDefinitionBuilder definition BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);validate(attributes);definition.addPropertyValue(url, getUrl(attributes));definition.addPropertyValue(path, getPath(attributes));String name getName(attributes);definition.addPropertyValue(name, name);String contextId getContextId(attributes);definition.addPropertyValue(contextId, contextId);definition.addPropertyValue(type, className);definition.addPropertyValue(decode404, attributes.get(decode404));definition.addPropertyValue(fallback, attributes.get(fallback));definition.addPropertyValue(fallbackFactory, attributes.get(fallbackFactory));definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);// 拼接别名String alias contextId FeignClient;AbstractBeanDefinition beanDefinition definition.getBeanDefinition();boolean primary (Boolean) attributes.get(primary); // has a default, wont be nullbeanDefinition.setPrimary(primary);// 配置了qualifier优先用qualifierString qualifier getQualifier(attributes);if (StringUtils.hasText(qualifier)) {alias qualifier;}BeanDefinitionHolder holder new BeanDefinitionHolder(beanDefinition, className,new String[] { alias });BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);} url url用于配置指定服务的地址相当于直接请求这个服务。像调试等场景可以使用。 FeignClient(name order-server, url http://localhost:8085) public interface OrderRemoteClient {GetMapping(/api/order/detail)public Order detail(RequestParam(orderId) String orderId); }path path定义当前FeignClient访问接口时的统一前缀。 比如接口地址是/order/detail, 如果你定义了前缀是order, 那么具体方法上的路径就只需要写/detail即可。 FeignClient(name order-server, url http://localhost:8085, path /api/order) public interface OrderRemoteClient {GetMapping(/detail)public Order detail(RequestParam(orderId) String orderId); }primary primary对应的是Primary注解默认为true官方这样设置也是有原因的。当我们的Feign实现了fallback后也就意味着Feign Client有多个相同的Bean在Spring容器中当我们在使用Autowired进行注入的时候不知道注入哪个所以我们需要设置一个优先级高的Primary注解就是干这件事情的。 qualifier qualifier对应的是Qualifier注解使用场景跟上面的primary关系很淡一般场景直接Autowired直接注入就可以了。 如果我们的Feign Client有fallback实现默认FeignClient注解的primarytrue, 意味着我们使用Autowired注入是没有问题的会优先注入你的Feign Client。 如果你鬼斧神差的把primary设置成false了直接用Autowired注入的地方就会报错不知道要注入哪个对象。 解决方案很明显你可以将primary设置成true即可如果由于某些特殊原因你必须得去掉primarytrue的设置这种情况下我们怎么进行注入我们可以配置一个qualifier然后使用Qualifier注解进行注入。 Feign Client 定义 FeignClient(name order-server, path /api/order, qualifierorderRemoteClient) public interface OrderRemoteClient {GetMapping(/detail)public Order detail(RequestParam(orderId) String orderId); }Feign Client注入 Autowired Qualifier(orderRemoteClient) private OrderRemoteClient orderRemoteClient;configuration configuration是配置Feign配置类在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。 configuration定义 public class FeignConfiguration {Beanpublic Logger.Level getLoggerLevel() {return Logger.Level.FULL;}Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor() {return new BasicAuthRequestInterceptor(user, password);}Beanpublic CustomRequestInterceptor customRequestInterceptor() {return new CustomRequestInterceptor();}// Contract,feignDecoder,feignEncoder..... }使用示列 FeignClient(value order-server, configuration FeignConfiguration.class) public interface OrderRemoteClient {GetMapping(/api/order/detail)public Order detail(RequestParam(orderId) String orderId);}fallback 定义容错的处理类也就是回退逻辑当调用远程接口失败或超时时会调用对应接口的容错逻辑fallback指定的类必须实现FeignClient标记的接口无法知道熔断的异常信息。 fallback定义 Component public class OrderRemoteClientFallback implements OrderRemoteClient {Overridepublic Order detail(String orderId) {return new Order(order-998, 默认fallback);}}使用示列 FeignClient(value order-server, fallback OrderRemoteClientFallback.class) public interface OrderRemoteClient {GetMapping(/api/order/detail)public Order detail(RequestParam(orderId) String orderId);}fallbackFactory 也是容错的处理可以知道熔断的异常信息。工厂类用于生成fallback类示例通过这个属性我们可以实现每个接口通用的容错逻辑减少重复的代码。 fallbackFactory定义 Component public class OrderRemoteClientFallbackFactory implements FallbackFactoryOrderRemoteClient {private Logger logger LoggerFactory.getLogger(OrderRemoteClientFallbackFactory.class);Overridepublic OrderRemoteClient create(Throwable cause) {return new OrderRemoteClient() {Overridepublic Order detail(String id) {logger.error(OrderRemoteClient.detail 异常, cause);return new Order(order-998, 默认);}};} }使用示列 FeignClient(value order-server, fallbackFactory OrderRemoteClientFallbackFactory.class) public interface OrderRemoteClient {GetMapping(/order/detail)public Order detail(RequestParam(orderId) String orderId);}FeignClient添加Header信息 在RequestMapping中添加 FeignClient(url ${orderServer_domain:http://order:8082},value order-server,contextId OrderServerClient,path /api/order) public interface OrderRemoteClient {RequestMapping(value/detail, method RequestMethod.POST,headers {Content-Typeapplication/json;charsetUTF-8})Order detail(RequestParam(orderId) String orderId); }使用RequestHeader注解添加 FeignClient(url ${orderServer_domain:http://order:8082},value order-server,contextId OrderServerClient,path /api/order) public interface OrderRemoteClient {RequestMapping(value/detail, method RequestMethod.POST)ListString detail(RequestHeader MapString, String headerMap, RequestParam(orderId) String orderId); }使用Headers注解添加 FeignClient(url ${orderServer_domain:http://order:8082},value order-server,contextId OrderServerClient,path /api/order) public interface OrderRemoteClient {RequestMapping(value/detail, method RequestMethod.POST)Headers({Content-Type: application/json;charsetUTF-8})ListString detail(RequestHeader MapString, String headerMap, RequestParam(orderId) String orderId); }实现RequestInterceptor接口 Configuration public class FeignRequestInterceptor implements RequestInterceptor {Overridepublic void apply(RequestTemplate temp) {temp.header(HttpHeaders.AUTHORIZATION, XXXXX);}}FeignClient 源码 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package org.springframework.cloud.openfeign;import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.annotation.AliasFor;Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented Inherited public interface FeignClient {AliasFor(name)String value() default ;String contextId() default ;AliasFor(value)String name() default ;String[] qualifiers() default {};String url() default ;boolean dismiss404() default false;Class?[] configuration() default {};Class? fallback() default void.class;Class? fallbackFactory() default void.class;String path() default ;boolean primary() default true; }
http://www.dnsts.com.cn/news/142099.html

相关文章:

  • 服装营销型网站建设wordpress 主页面错乱
  • 做相亲网站 一年赚千万wordpress 媒体路径
  • 网站建设中搭建页面结构织梦dedecms医院类网站在线预约挂号插件
  • 建设银行 钓鱼网站浙江众安建设集团有限公司网站
  • 阿里网站建设视频教程wordpress uc用户中心
  • 网站开发简介php建设网站后台
  • 诸暨企业网站建设seo发帖论坛
  • 网站设计酷站大连招标投标信息网
  • 做策划有帮助的网站网站建设空间空间有几种类型
  • 网站建设文字表达最专业的做网站公司
  • 网站怎么做微信接口在线crm软件有哪些优势?
  • 泰安营销型网站建设网站建设模板案例响应式
  • 网站建设低价建站损失在哪里wordpress 图库插件
  • 网站建设需要交印花税吗网站后期维护怎么做
  • 网站选服务器文件英铭长沙网站建设
  • 公司网站手机版美食网站策划书范文
  • 网站前端程序制作开发策划企业宣传片策划制作
  • 百度推广建设网站是干什么了做网站大概价格
  • 东莞营销网站建设价格大专学网站开发
  • 公司网站需要多少钱可以上传资源的网站开发费用
  • 南京h5 网站建设小程序注册认证流程
  • 阿里云虚拟主机做淘客网站公司变更登记申请表
  • 模板网站一天建好百度收录api怎么提交
  • 红河北京网站建设电子商务网站建设实训室简介
  • 北京外贸营销网站建设费用装修平台网络推广公司
  • wordpress显示最新评论google搜索排名优化
  • 专题网站建设自查整改报告太原电脑培训班哪家好
  • 医疗网站备案要怎么做 需要准备什么材料昆明网站开发培训机构
  • 学校做网站有些什么好处常州新北建设局网站
  • 一些网站是用什么颜色做的wordpress外链视频播放