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

比眉伴天荒 2023-10-03 21:38 68阅读 0赞

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…

format_png

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

2. 核心类介绍

2.1 @EnableFeignClients

  1. // @EnableFeignClients注解用来启动FeignClient,以支持Feign。
  2. // 该注解可以通过配置,扫描指定位置的@FeignClient注解声明的Feign客户端接口
  3. @Retention(RetentionPolicy.RUNTIME)
  4. @Target(ElementType.TYPE)
  5. @Documented
  6. @Import(FeignClientsRegistrar.class)
  7. public @interface EnableFeignClients {
  8. // value和basePackage具有相同的功能,其中value是basePackage的别名
  9. // value和basePackage只能同时使用一个
  10. /**
  11. * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
  12. * declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
  13. * {@code @ComponentScan(basePackages="org.my.pkg")}.
  14. * @return the array of 'basePackages'.
  15. */
  16. // 为basePackages属性的别名,允许使用更简洁的书写方式。例如:@EnableFeignClients({"com.cd", "com.ad"})
  17. String[] value() default {};
  18. /**
  19. * Base packages to scan for annotated components.
  20. * <p>
  21. * {@link #value()} is an alias for (and mutually exclusive with) this attribute.
  22. * <p>
  23. * Use {@link #basePackageClasses()} for a type-safe alternative to String-based
  24. * package names.
  25. * @return the array of 'basePackages'.
  26. */
  27. // 设置自动扫描带有@FeignClient注解的基础包路径。例如 @EnableFeignClients(basePackages = {"com.cd", "com.ad"})
  28. String[] basePackages() default {};
  29. /**
  30. * Type-safe alternative to {@link #basePackages()} for specifying the packages to
  31. * scan for annotated components. The package of each class specified will be scanned.
  32. * <p>
  33. * Consider creating a special no-op marker class or interface in each package that
  34. * serves no purpose other than being referenced by this attribute.
  35. * @return the array of 'basePackageClasses'.
  36. */
  37. // 该属性是basePackages属性的安全替代属性。该属性将扫描指定的每个类所在的包下面的所有被@FeignClient修饰的类;
  38. // 这需要考虑在每个包中创建一个特殊的标记类或接口,该类或接口除了被该属性引用外,没有其他用途
  39. Class<?>[] basePackageClasses() default {};
  40. /**
  41. * A custom <code>@Configuration</code> for all feign clients. Can contain override
  42. * <code>@Bean</code> definition for the pieces that make up the client, for instance
  43. * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
  44. *
  45. * @see FeignClientsConfiguration for the defaults
  46. * @return list of default configurations
  47. */
  48. // 该属性用来自定义所有Feign客户端的配置,使用@Configuration进行配置。
  49. // 当然也可以为某一个Feign客户端进行配置。具体配置方法见@FeignClient的configuration属性。
  50. Class<?>[] defaultConfiguration() default {};
  51. /**
  52. * List of classes annotated with @FeignClient. If not empty, disables classpath
  53. * scanning.
  54. * @return list of FeignClient classes
  55. */
  56. // 设置由@FeignClient注解修饰的类列表。如果clients不是空数组,则不通过类路径自动扫描功能来加载FeignClient
  57. // 例如 @EnableFeignClients(clients = {SchedualService.class})
  58. // 上面代码中引入FeignClient客户端SchedualService,且也只引入该FeignClient客户端。
  59. Class<?>[] clients() default {};
  60. }
  61. 复制代码

2.2 @FeignClient

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface FeignClient {
  5. // name 和 value 两个属性等价,至少要配置一个
  6. /**
  7. * The name of the service with optional protocol prefix. Synonym for {@link #name()
  8. * name}. A name must be specified for all clients, whether or not a url is provided.
  9. * Can be specified as property key, eg: ${propertyKey}.
  10. * @return the name of the service with optional protocol prefix
  11. */
  12. @AliasFor("name")
  13. String value() default "";
  14. /**
  15. * The service id with optional protocol prefix. Synonym for {@link #value() value}.
  16. * @deprecated use {@link #name() name} instead
  17. * @return the service id with optional protocol prefix
  18. */
  19. @Deprecated
  20. String serviceId() default "";
  21. /**
  22. * This will be used as the bean name instead of name if present, but will not be used
  23. * as a service id.
  24. * @return bean name instead of name if present
  25. */
  26. // 别名,假设一个User服务有两个FeignClient,都需要调用Product服务, 因为name属性值一样,所以需要通过配置contextId来区分,否则启动项目时会报错
  27. String contextId() default "";
  28. /**
  29. * @return The service id with optional protocol prefix. Synonym for {@link #value()
  30. * value}.
  31. */
  32. @AliasFor("value")
  33. String name() default "";
  34. /**
  35. * @return the <code>@Qualifier</code> value for the feign client.
  36. */
  37. // 返回默认值=contextId+“FeignClient”。
  38. String qualifier() default "";
  39. /**
  40. * @return an absolute URL or resolvable hostname (the protocol is optional).
  41. */
  42. // 请求地址, 没配置的话, 会把name/value的属性值当成服务名进行调用, 配置的话则使用url的值
  43. String url() default "";
  44. /**
  45. * @return whether 404s should be decoded instead of throwing FeignExceptions
  46. */
  47. // 当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  48. boolean decode404() default false;
  49. /**
  50. * A custom configuration class for the feign client. Can contain override
  51. * <code>@Bean</code> definition for the pieces that make up the client, for instance
  52. * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
  53. *
  54. * @see FeignClientsConfiguration for the defaults
  55. * @return list of configurations for feign client
  56. */
  57. // Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  58. Class<?>[] configuration() default {};
  59. /**
  60. * Fallback class for the specified Feign client interface. The fallback class must
  61. * implement the interface annotated by this annotation and be a valid spring bean.
  62. * @return fallback class for the specified Feign client interface
  63. */
  64. // 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  65. Class<?> fallback() default void.class;
  66. /**
  67. * Define a fallback factory for the specified Feign client interface. The fallback
  68. * factory must produce instances of fallback classes that implement the interface
  69. * annotated by {@link FeignClient}. The fallback factory must be a valid spring bean.
  70. *
  71. * @see feign.hystrix.FallbackFactory for details.
  72. * @return fallback factory for the specified Feign client interface
  73. */
  74. // 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  75. Class<?> fallbackFactory() default void.class;
  76. /**
  77. * @return path prefix to be used by all method-level mappings. Can be used with or
  78. * without <code>@RibbonClient</code>.
  79. */
  80. // 所有方法级映射使用的路径前缀
  81. String path() default "";
  82. /**
  83. * @return whether to mark the feign proxy as a primary bean. Defaults to true.
  84. */
  85. // 是否将外部代理标记为主bean。默认为true。
  86. boolean primary() default true;
  87. }
  88. 复制代码

2.3 FeignClientSpecification

FeignClientSpecification是 Feign Client 生成规范:

format_png 1

2.4 FeignContext

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

  1. // FeignContext 是一个为 Feign Client 创建所准备的上下文对象
  2. public class FeignContext extends NamedContextFactory<FeignClientSpecification> {
  3. public FeignContext() {
  4. super(FeignClientsConfiguration.class, "feign", "feign.client.name");
  5. }
  6. }
  7. 复制代码

其父类为:

  1. public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
  2. implements DisposableBean, ApplicationContextAware {
  3. private final String propertySourceName;
  4. private final String propertyName;
  5. // todo 该 map 的 key 为 FeignClient 的名称(其所要调用的微服务名称), value 是组装这个
  6. // FeignClient 所必须的组件所在的 Spring 子容器
  7. private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
  8. // 这个map中存放的是@EnableFeignClients与@FeignClient两个注解中的configuration属性值。
  9. // 这个属性值只有两类:
  10. // 第一类只有一个,其 key 为字符串 default + 当前启动类的全限定性类名 ,例如:
  11. // default.com.abc.ConsumerFeign8080, value 为@EnableFeignClients 的 defaultConfiguration属性值
  12. // 第二类有多个,其 key 为当前@FeignClient 的名称, value 为这个注解的 configuration 属性值
  13. private Map<String, C> configurations = new ConcurrentHashMap<>();
  14. private ApplicationContext parent;
  15. private Class<?> defaultConfigType;
  16. public NamedContextFactory(Class<?> defaultConfigType, String propertySourceName,
  17. String propertyName) {
  18. this.defaultConfigType = defaultConfigType;
  19. this.propertySourceName = propertySourceName;
  20. this.propertyName = propertyName;
  21. }

发表评论

表情:
评论列表 (有 0 条评论,68人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDK环境

    > 本教程是用idea搭建,jdk源码就在jdk安装路径下的src.zip中,解压即可用。 第一步:新建项目 打开IDEA,按如下步骤新建一个简单Java项目 cre

    相关 mybatis环境

    前言 mybatis在众多的数据持久化框架中应该说是目前使用最多的,其优秀的设计和底层封装,值得很多开发人员进行学习,下面让我们先来构建一下mybatis的源码阅读环境吧

    相关 直播系统说明

    直播市场的火爆不得不让人吃惊,直播平台的搭建更成为了企业取得成功的第一要素,那么直播源码搭建直播平台的工作都有哪些呢?   首先是退流端的搭建。直播推流端即主播端,主要通过手机

    相关 CETK环境说明

                          CETK环境搭建及说明 作者:ARM-WINCE 微软提供的CETK可以帮助测试BSP包括驱动,OAL。针对每个驱动,都会有

    相关 dubbo环境

    dubbo由于很多jar包无法下载到而在导入后存在大量错误。这里记录一下解决方案。         1、通过maven安装alibaba open parent。地址http