美文网首页
Feign源码学习(1)

Feign源码学习(1)

作者: 無式 | 来源:发表于2017-08-26 12:20 被阅读0次
    • 最早是在看Spring Cloud的时候了解到Feign框架,Netflix的标准用法是Feign+Ribbon+Hystrix,来达到请求的客户端负载均衡+错误熔断。

    OpenFeign

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-core</artifactId>
        <version>{版本号,例:9.5.1}</version>
    </dependency>
    

    框架入口类:feign.Feign.java

    • 官网示例:
    // 创建GitHub的API调用对象
    GitHub github = Feign.builder()
                           .decoder(new GsonDecoder())
                           .target(GitHub.class, "https://api.github.com");
    
    • 通过Feign.builder,指定接口(GitHub.class)及其他参数,利用反射+代理的方式生成接口调用实现类。
    • 可配置的参数包括:
      • client:HTTP请求Client,默认使用java.net.HttpURLConnection实现。支持OkHttp, ApacheHttp等。
      • encoder&decoder:Body参数与返回结果解析器。支持Gson, Jackson,JAXB等。
      • retryer:请求重试参数。
      • options:请求超时设置。
      • errorDecoder:请求错误内容解析器。
      • requestInterceptors:请求拦截器。通过RequestInterceptor可以设置Header信息,实现无状态接口请求认证。

    Feign.Builder 设置接口客户端生成参数

    • 为了方便使用者,采用builder模式:
      //Feign.Builder 部分代码
      public static class Builder {
        private Logger.Level logLevel = Logger.Level.NONE;
        private Contract contract = new Contract.Default();
        private Client client = new Client.Default(null, null);
        private Retryer retryer = new Retryer.Default();
        private Logger logger = new NoOpLogger();
        private Encoder encoder = new Encoder.Default();
        private Decoder decoder = new Decoder.Default();
    
        public Builder logLevel(Logger.Level logLevel) {
          this.logLevel = logLevel;
          return this;  //设置参数后返回this
        }
    
        public Builder contract(Contract contract) {
          this.contract = contract;
          return this;
        }
    
        public Builder client(Client client) {
          this.client = client;
          return this;
        }
    
        public Builder retryer(Retryer retryer) {
          this.retryer = retryer;
          return this;
        }
    
        public Builder logger(Logger logger) {
          this.logger = logger;
          return this;
        }
    
        public Builder encoder(Encoder encoder) {
          this.encoder = encoder;
          return this;
        }
    
        public Builder decoder(Decoder decoder) {
          this.decoder = decoder;
          return this;
        }
    }
    
    • Builber模式可以使得创建一个对象变成链式调用,而不需要重复调用多行的setter函数。

    Feign.Builder.target 指定要生成代理的接口类

    • 传入接口类与host地址,生成接口的代理实现类。
      //Feign.Builder 部分代码
      public static class Builder {
        public <T> T target(Class<T> apiType, String url) {
          return target(new HardCodedTarget<T>(apiType, url));
        }
    
        public <T> T target(Target<T> target) {
          return build().newInstance(target);
        }
    
        public Feign build() {
          SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
              new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger, logLevel, decode404);
          ParseHandlersByName handlersByName = 
              new ParseHandlersByName(contract, options, encoder, decoder, 
                                        errorDecoder, synchronousMethodHandlerFactory);
          return new ReflectiveFeign(handlersByName, invocationHandlerFactory);
        }
      }
    
    • target创建Feign的默认实现ReflectiveFeign,并调用newInstance方法利用反射+Proxy机制创建apiType的实现对象。

    相关文章

      网友评论

          本文标题:Feign源码学习(1)

          本文链接:https://www.haomeiwen.com/subject/qqumdxtx.html