纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Spring Cloud Feign原理 Spring Cloud Feign原理详解

起岸星辰   2021-06-07 我要评论
想了解Spring Cloud Feign原理详解的相关内容吗起岸星辰在本文为您仔细讲解Spring Cloud Feign原理的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Spring,Cloud,Feign,Feign原理下面大家一起来学习吧

Feign 主要是帮助我们方便进行rest api服务间的调用其大体实现思路就我们通过标记注解在一个接口类上(注解上将包含要调用的接口信息)之后在调用时根据注解信息组装好请求信息接下来基于ribbon这些负载均衡器来生成真实的服务地址最后将请求发送出去之后将接收到的结果反序列化为相关的Java对象供我们直接使用 下面我们走进Spring Cloud对feign封装的源码中去了解其主要实现机制

Feign的大体机制

通过在启动类上标记 @EnableFeignClients 注解来开启feign的功能服务启动后会扫描 @FeignClient 注解标记的接口然后根据扫描的注解信息为每个接口类生成feign客户端请求同时解析接口方法中的Spring MVC的相关注解通过专门的注解解析器识别这些注解信息以便后面可以正确的组装请求参数使用 Ribbon 和 Eureka 获取到请求服务的真实地址等信息最后使用 http 相关组件进行执行调用其大致流程图如下:

@EnableFeignClients 和 @FeignClient 注解

在EnableFeignClients 注解类中有一个 @Import(FeignClientsRegistrar.class)的配置

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
// 引入FeignClientsRegistrar 来扫描@FeignClient注解下的类
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
    ...
}

我们追踪代码进入到FeignClientsRegistrar类中会发现FeignClientsRegistrar 类实现了ImportBeanDefinitionRegistrar(在spring context 项目中)接口因此spring boot启动时会调用它的registerBeanDefinitions()方法该方法中会扫描 EnableFeignClients 和 FeignClient 注解信息并设置相关信息

/**
 * spring boot 启动时会自动调用 ImportBeanDefinitionRegistrar 入口方法
 */
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata
        , BeanDefinitionRegistry registry) {
    // 读取 @EnableFeignClients 注解中信息
    registerDefaultConfiguration(metadata, registry);
    // 扫描所有@FeignClient注解的类
    registerFeignClients(metadata, registry);
}

registerDefaultConfiguration方法

在registerDefaultConfiguration()方法中会读取@EnableFeignClients注解信息然后将这些信息注册到一个 BeanDefinitionRegistry 里面去之后feign的一些默认配置将通过这里注册的信息中取获取

registerFeignClients方法

  • registerFeignClients()方法会扫描相关包路径(如果EnableFeignClients的basePackages没有配置默认会直接使用启动类所在的包路径)下所有的@FeiginClient注解的类
  • 然后根据@FeiginClient注解信息向BeanDefinitionRegistry里面注册bean注意这里设置的bean名称生成规则是使用服务名+FeignClientSpecification.class.getSimpleName()因此如果对一个服务写多个接口类会发生bean名称重复导致注册失败所以需要增加一个 allow-bean-definition-overriding: true 的配置
  • 最后会调用 registerFeignClient() 方法注册feign客户端这里的bean名称的为当前接口类的类路径

其流程图如下:

feign客户端的动态代理

上面registerFeignClient()方法中在构建bean的时候实际构建的是FeignClientFactoryBean

BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);

FeignClientFactoryBean 类对父类的getObject()方法进行了重写后面动态代理时使用的就是它来获取feign client的在这里会根据上面注解配置同时会读取application.yml配置信息根据配置来设置feign的相关信息比如编解码器、注解解析器、请求超时时间等之后如果没有设置url那么就会和负载均衡器(ribbon)整合最后会通过反射将接口中相关方法进行解析保存供后面进行jdk代理使用

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  // 判断是否是不需要代理的
    if ("equals".equals(method.getName())) {
    try {
      Object otherHandler =
          args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
      return equals(otherHandler);
    } catch (IllegalArgumentException e) {
      return false;
    }
  } else if ("hashCode".equals(method.getName())) {
    return hashCode();
  } else if ("toString".equals(method.getName())) {
    return toString();
  }
  // 需要代理执行代理方法
  return dispatch.get(method).invoke(args);
}


相关文章

猜您喜欢

  • rabbitmq routingkey作用 rabbitmq中routingkey的作用说明

    想了解rabbitmq中routingkey的作用说明的相关内容吗张超帅在本文为您仔细讲解rabbitmq routingkey作用的相关知识和一些Code实例欢迎阅读和指正我们先划重点:rabbitmq,routingkey作用下面大家一起来学习吧..
  • SpringBoot邮件任务 SpringBoot任务之详解邮件任务

    想了解SpringBoot任务之详解邮件任务的相关内容吗Z && Y在本文为您仔细讲解SpringBoot邮件任务的相关知识和一些Code实例欢迎阅读和指正我们先划重点:SpringBoot邮件任务,SpringBoot任务下面大家一起来学习吧..

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式