OpenFeign源码1-环境搭建及核心类说明

news2024/11/23 15:50:20

0. 环境

  • nacos版本:1.4.1
  • Spring Cloud : Hoxton.SR9(没用2020.0.2版本后面说明
  • Spring Boot :2.4.4
  • Spring Cloud alibaba: 2.2.5.RELEASE
  • Spring Cloud openFeign 2.2.2.RELEASE

测试代码:github.com/hsfxuebao/s…

2020.0.X版本开始的OpenFeign底层不再使用Ribbon了

1. 下载

github地址:github.com/spring-clou…

由于是maven工程,直接导入IDEA中就可以了

2. 核心类介绍

2.1 @EnableFeignClients

// @EnableFeignClients注解用来启动FeignClient,以支持Feign。
// 该注解可以通过配置,扫描指定位置的@FeignClient注解声明的Feign客户端接口
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {

   // value和basePackage具有相同的功能,其中value是basePackage的别名
   // value和basePackage只能同时使用一个
   /**
    * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
    * declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
    * {@code @ComponentScan(basePackages="org.my.pkg")}.
    * @return the array of 'basePackages'.
    */
   // 为basePackages属性的别名,允许使用更简洁的书写方式。例如:@EnableFeignClients({"com.cd", "com.ad"})
   String[] value() default {};

   /**
    * Base packages to scan for annotated components.
    * <p>
    * {@link #value()} is an alias for (and mutually exclusive with) this attribute.
    * <p>
    * Use {@link #basePackageClasses()} for a type-safe alternative to String-based
    * package names.
    * @return the array of 'basePackages'.
    */
   // 设置自动扫描带有@FeignClient注解的基础包路径。例如 @EnableFeignClients(basePackages = {"com.cd", "com.ad"})
   String[] basePackages() default {};

   /**
    * Type-safe alternative to {@link #basePackages()} for specifying the packages to
    * scan for annotated components. The package of each class specified will be scanned.
    * <p>
    * Consider creating a special no-op marker class or interface in each package that
    * serves no purpose other than being referenced by this attribute.
    * @return the array of 'basePackageClasses'.
    */
   // 该属性是basePackages属性的安全替代属性。该属性将扫描指定的每个类所在的包下面的所有被@FeignClient修饰的类;
   // 这需要考虑在每个包中创建一个特殊的标记类或接口,该类或接口除了被该属性引用外,没有其他用途
   Class<?>[] basePackageClasses() default {};

   /**
    * A custom <code>@Configuration</code> for all feign clients. Can contain override
    * <code>@Bean</code> definition for the pieces that make up the client, for instance
    * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
    *
    * @see FeignClientsConfiguration for the defaults
    * @return list of default configurations
    */
   // 该属性用来自定义所有Feign客户端的配置,使用@Configuration进行配置。
   // 当然也可以为某一个Feign客户端进行配置。具体配置方法见@FeignClient的configuration属性。
   Class<?>[] defaultConfiguration() default {};

   /**
    * List of classes annotated with @FeignClient. If not empty, disables classpath
    * scanning.
    * @return list of FeignClient classes
    */
   // 设置由@FeignClient注解修饰的类列表。如果clients不是空数组,则不通过类路径自动扫描功能来加载FeignClient
   // 例如 @EnableFeignClients(clients = {SchedualService.class})
   // 上面代码中引入FeignClient客户端SchedualService,且也只引入该FeignClient客户端。
   Class<?>[] clients() default {};

}
复制代码

2.2 @FeignClient

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {

   // name 和 value 两个属性等价,至少要配置一个
   /**
    * The name of the service with optional protocol prefix. Synonym for {@link #name()
    * name}. A name must be specified for all clients, whether or not a url is provided.
    * Can be specified as property key, eg: ${propertyKey}.
    * @return the name of the service with optional protocol prefix
    */
   @AliasFor("name")
   String value() default "";

   /**
    * The service id with optional protocol prefix. Synonym for {@link #value() value}.
    * @deprecated use {@link #name() name} instead
    * @return the service id with optional protocol prefix
    */
   @Deprecated
   String serviceId() default "";

   /**
    * This will be used as the bean name instead of name if present, but will not be used
    * as a service id.
    * @return bean name instead of name if present
    */
   // 别名,假设一个User服务有两个FeignClient,都需要调用Product服务, 因为name属性值一样,所以需要通过配置contextId来区分,否则启动项目时会报错
   String contextId() default "";

   /**
    * @return The service id with optional protocol prefix. Synonym for {@link #value()
    * value}.
    */
   @AliasFor("value")
   String name() default "";

   /**
    * @return the <code>@Qualifier</code> value for the feign client.
    */
   // 返回默认值=contextId+“FeignClient”。
   String qualifier() default "";

   /**
    * @return an absolute URL or resolvable hostname (the protocol is optional).
    */
   // 请求地址, 没配置的话, 会把name/value的属性值当成服务名进行调用, 配置的话则使用url的值
   String url() default "";

   /**
    * @return whether 404s should be decoded instead of throwing FeignExceptions
    */
   // 当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
   boolean decode404() default false;

   /**
    * A custom configuration class for the feign client. Can contain override
    * <code>@Bean</code> definition for the pieces that make up the client, for instance
    * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
    *
    * @see FeignClientsConfiguration for the defaults
    * @return list of configurations for feign client
    */
   // Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
   Class<?>[] configuration() default {};

   /**
    * Fallback class for the specified Feign client interface. The fallback class must
    * implement the interface annotated by this annotation and be a valid spring bean.
    * @return fallback class for the specified Feign client interface
    */
   // 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
   Class<?> fallback() default void.class;

   /**
    * Define a fallback factory for the specified Feign client interface. The fallback
    * factory must produce instances of fallback classes that implement the interface
    * annotated by {@link FeignClient}. The fallback factory must be a valid spring bean.
    *
    * @see feign.hystrix.FallbackFactory for details.
    * @return fallback factory for the specified Feign client interface
    */
   // 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
   Class<?> fallbackFactory() default void.class;

   /**
    * @return path prefix to be used by all method-level mappings. Can be used with or
    * without <code>@RibbonClient</code>.
    */
   // 所有方法级映射使用的路径前缀
   String path() default "";

   /**
    * @return whether to mark the feign proxy as a primary bean. Defaults to true.
    */
   // 是否将外部代理标记为主bean。默认为true。
   boolean primary() default true;

}
复制代码

2.3 FeignClientSpecification

FeignClientSpecification 是 Feign Client 生成规范:

2.4 FeignContext

FeignContext 是一个为 Feign Client 创建所准备的上下文对象

// FeignContext 是一个为 Feign Client 创建所准备的上下文对象
public class FeignContext extends NamedContextFactory<FeignClientSpecification> {

   public FeignContext() {
      super(FeignClientsConfiguration.class, "feign", "feign.client.name");
   }

}
复制代码

其父类为:

public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
      implements DisposableBean, ApplicationContextAware {

   private final String propertySourceName;

   private final String propertyName;

   // todo 该 map 的 key 为 FeignClient 的名称(其所要调用的微服务名称), value 是组装这个
   // FeignClient 所必须的组件所在的 Spring 子容器
   private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();

    // 这个map中存放的是@EnableFeignClients与@FeignClient两个注解中的configuration属性值。
    // 这个属性值只有两类:
    // 第一类只有一个,其 key 为字符串 default + 当前启动类的全限定性类名 ,例如:
// default.com.abc.ConsumerFeign8080, value 为@EnableFeignClients 的 defaultConfiguration属性值
    // 第二类有多个,其 key 为当前@FeignClient 的名称, value 为这个注解的 configuration 属性值
   private Map<String, C> configurations = new ConcurrentHashMap<>();

   private ApplicationContext parent;

   private Class<?> defaultConfigType;

   public NamedContextFactory(Class<?> defaultConfigType, String propertySourceName,
         String propertyName) {
      this.defaultConfigType = defaultConfigType;
      this.propertySourceName = propertySourceName;
      this.propertyName = propertyName;
   }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/23494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebDAV之葫芦儿·派盘+PassStore

PassStore 支持webdav方式连接葫芦儿派盘。 大家常用的qq,手机微信,新浪微博等。假如各个网址都设成同样的帐号和登陆密码,一旦某一帐户泄漏了,别的平台上的账户密码都有被撞库攻击的风险。在不一样的站点设定不一样的高韧性登陆密码才算是最安全可靠的确保,殊不知这般繁…

c++调用tf.keras的模型

​ 环境&#xff1a; ubuntu 20.04 python 3.8 tensorflow-gpu 2.4.0 显卡 nvidia rtx A6000 驱动 495.29.05 cuda 11.5 cudnn 8.3.0 tensorRT 8.4 1.将keras保存的h5模型转成darknet的weight&#xff0c;然后用opencv加载 cv::dnn::Net net cv::dnn::readNetFromDar…

链表中快慢指针的应用

目录 一、链表的中间结点 二、回文链表 三、链表中倒数第K个结点 四、删除链表的倒数第n个结点 一、链表的中间结点 给定一个头结点为 head 的非空单链表&#xff0c;返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 先设置两个low和fast都指…

【MySQL】测试题03

文章目录1、创建数据库2、使用数据库3、创建数据表【3.1】创建学生信息表Student【3.2】创建课程信息表Course【3.3】创建教师信息表Teacher【3.4】创建成绩信息表Score4、添加数据【4.1】向学生student表添加数据【4.2】向课程course表添加数据【4.3】向教师信息teacher表添加…

【动手学深度学习】softmax回归的从零开始实现(PyTorch版本)(含源代码)

目录&#xff1a;softmax回归的从零开始实现一、理论基础1.1 前言1.2 分类问题1.3 网络架构1.4 全连接层的参数开销1.5 softmax运算1.6 小批量样本的矢量化1.7 损失函数1.7.1 对数似然1.7.2 softmax及其导数1.7.3 交叉熵损失1.8 信息论基础1.8.1 熵1.8.2 信息量1.8.3 重新审视交…

19 02-检索满足客户端定义的状态掩码的DTC列表

诊断协议那些事儿 诊断协议那些事儿专栏系列文章&#xff0c;19服务作为UDS中子功能最多的服务&#xff0c;一共有28种子功能&#xff0c;本文将介绍常用的19 02服务&#xff1a;根据状态掩码读取DTC列表。 关联文章&#xff1a; 19服务List 19 01-通过状态掩码读取DTC数目 …

详细教程。2022年滁州市明光市、来安县等各地区高新技术企业申报

安徽省大力鼓励企业申报高新技术企业&#xff0c;于高企申报也有很多奖补。滁州市企业申报奖补政策发布&#xff0c;企业可以根据自身情况申请奖补&#xff0c;奖补金额为10万元至30万元不等&#xff0c;明光市&#xff0c;凤阳县等各地区奖补申请可以通过市级机关办理。 下面小…

跟艾文学编程《Python数据可视化》(01)基于Plotly的动态可视化绘图

作者&#xff1a;艾文&#xff0c;计算机硕士学位&#xff0c;企业内训讲师和金牌面试官&#xff0c;公司资深算法专家&#xff0c;现就职BAT一线大厂。邮箱&#xff1a;1121025745qq.com博客&#xff1a;https://wenjie.blog.csdn.net/内容&#xff1a;跟艾文学编程《Python数…

2022-11-21 mysql列存储引擎-架构实现缺陷梳理-P2

摘要: 收集现有代码的糟糕实现&#xff0c;前事不忘后事之师&#xff0c;把这些烂东西定死在耻辱柱上以免再次发生 糟糕的设计: 一. DGMaterializedIterator::GetNextPackrow 函数实现: int DimensionGroupMaterialized::DGMaterializedIterator::GetNextPackrow(int dim, int…

【Linux系统】第一篇:基础指令篇

文章目录一、Linux中的文件二、Linux用户三、Linux基本指令ls指令pwd命令cd指令touch指令mkdir指令rmdir指令rm 指令man指令cp指令mv指令cat指令tac指令more指令less指令head指令tail指令管道重定向date指令cal指令find指令which指令alias指令whereis指令grep指令wc指令sort指令…

Node的web编程(二)

一、JSON数据 1、定义 JavaScript Object Notation&#xff0c;是一种轻量级的前后端数据交换的格式(数据格式)。 2、特点 &#xff08;1&#xff09;容易阅读和编写 &#xff08;2&#xff09;语言无关性 &#xff08;3&#xff09;便于编译、解析 3、语法要求 &#…

Mac m1配置flutter开发环境

Mac m1配置flutter开发环境 文章目录Mac m1配置flutter开发环境一、下载Android Studio二、下载flutter sdk三、新建flutter project四、使用在线环境进行Flutter开发Dart在线运行环境Flutter在线运行环境一、下载Android Studio 进入官网下载&#xff0c;选择苹果芯片版本。 …

【Spring(三)】熟练掌握Spring的使用

有关Spring的所有文章都收录于我的专栏&#xff1a;&#x1f449;Spring&#x1f448; 目录 一、前言 二、通过静态工厂获取对象 三、通过实例工厂获取对象 四、通过FactoryBean获取对象 五、Bean配置信息重用 六、Bean创建顺序 七、Bean对象的单例和多例 八、Bean的生命周期 九…

Weblogic SSRF 漏洞(CVE-2014-4210)分析

Weblogic SSRF 漏洞是一个比较经典的SSRF 漏洞案例&#xff0c;该漏洞存在于 http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries. jsp 页面中&#xff0c;如图 1-1 所示图 1-1 Weblogic SSRF 漏洞Weblogic SSRF 漏洞可以通过向服务端发送以下请求参数进行触发&#x…

ARFoundation系列讲解 - 70 HumanBodyTracking3D

---------------------------------------------- 视频教程来源于网络,侵权必删! --------------------------------------------- 一、简介 HumanBodyTracking3D(身体跟踪3D)案例,当设备检查到人体时,会返回检测到人体关节点的3D空间位置(需要在iOS 13或更高版本的A12…

瞪羚优化算法(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Java集合类——ArrayList(扩容机制)

线性表 线性表是n个相同类型元素的有限序列&#xff0c;逻辑上连续物理上不一定是连续的&#xff0c;存储结构上分为顺序存储和链式存储&#xff0c;常见的线性表有&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列…… ArrayList 数据结构 ArrayList&am…

赋值运算符重载,取地址及const取地址操作符重载

赋值运算符重载1.运算符重载2.赋值运算符重载3.取地址及const取地址操作符重载如果一个类中什么成员都没有&#xff0c;那么该类简称为空类。而空类中其实并不是真的什么都没有&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。构造函数&…

同花顺_代码解析_技术指标_V,W

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 V&R VMA VMACD VOSC VPT VR VRFS VRSI VSTD W&R WVAD V&R 波动区间 用来衡量该股的市场波动风险.即95%的概率波动区间. 行号 1 n -> 250 2 x -> 收…

【考研英语语法】状语从句精讲

一、状语从句概述 &#xff08;一&#xff09;状语从句的含义 状语从句&#xff0c;指的就是一个句子作状语&#xff0c;表达“描述性的信息”&#xff0c;补充说明另一个句子&#xff08;主句&#xff09;。描述性的信息有很多种&#xff0c;可以描述时间、地点、原因、结果…