Web服务客户端之Feign

前文介绍了实现客户端负载均衡的Ribbon,但直接使用Ribbon的API来实现服务间的调用相对较为繁琐,服务间的调用能否像本地接口调用一样便捷、透明,更符合编程习惯呢?Feign就是用来干这事的。

Feign

Feign是一个声明式的Web服务客户端,让服务之间的调用变得非常简单——定义带@FeignClient注解的接口,本地直接@Autowired 接口,通过调用接口的方法来实现远程服务的调用。

 支持的注解包括Feign注解与JAX-RS(Java API for RESTful Web Services)注解。

 每一个Feign的客户端都包含一系列对应的组件,Spring Cloud通过FeignClientsConfiguration 为每一个命名的Feign客户端创建一个组件集合,包括feign.Decoder,feign.Encoder,feign.Contract等。

 

Feign提供的默认bean实现及说明

Bean类型默认实现类说明
DecoderResponseEntityDecoderResponseEntityDecoder封装了SpringDecoder,解码器,将服务的响应消息进行解码
EncoderSpringEncoder编码器
LoggerSlf4jLogger日志框架
ContractSpringMvcContract支持注解契约,使用SpringMvcContract可以对Spring MVC注解提供支持
Feign.BuilderHystrixFeign.Builder使用断路器来装饰Feign接口
ClientLoadBalancerFeignClient如果是ribbon则 LoadBalancerFeignClient, 如果是spring cloud LoadBalancer 则 FeignBlockingLoadBalancerClient,默认ribbon

 

跟Ribbon类似,可以通过配置类来自定义Feign客户端,如

复制代码

@FeignClient(name = "hello-service", configuration = CustomConfiguration.class)
public interface StoreClient {
    //..
}

public class CustomConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }
}

复制代码

 

这样Feign客户端就包含了FeignClientsConfiguration 与CustomConfiguration 中定义的组件,并且后者会覆盖前者(即自定义配置的优先级高于默认配置)。 

 

自定义配置类不需要加注解@Configuration,如果加了且被@ComponentScan扫描到,则将成为所有Feign客户端的默认配置

 

同样Feign客户端也支持通过配置文件来配置

复制代码

feign:
    client:
        config:
            feignName:
                connectTimeout: 5000
                readTimeout: 5000
                loggerLevel: full
                errorDecoder: com.example.SimpleErrorDecoder
                retryer: com.example.SimpleRetryer
                requestInterceptors:
                    - com.example.FooRequestInterceptor
                    - com.example.BarRequestInterceptor
                decode404: false
                encoder: com.example.SimpleEncoder
                decoder: com.example.SimpleDecoder
                contract: com.example.SimpleContract

复制代码

 


对于应用于所有Feign客户端的全局默认配置,也可以通过两种方式 

  1. 通过@EnableFeignClients 的defaultConfiguration 属性指定默认配置类

  2. 在配置文件中通过名称为default的配置实现

    复制代码

    feign:
        client:
            config:
                default:
                    connectTimeout: 5000
                    readTimeout: 5000
                    loggerLevel: basic

    复制代码

     

优先级同Ribbon, 配置文件>自定义配置类>默认的FeignClientsConfiguration


案例演示

本文案例演示基于前面搭建的springcloud-eureka 与 springcloud-eureka-client 两个示例项目。
 

  1. 新建springcloud-feign项目,pom.xml中加入依赖

    复制代码

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    复制代码

     spring-cloud-starter-openfeign 包含了spring-cloud-starter-netflix-ribbon 与 spring-cloud-starter-loadbalancer。

 

  1. 启动类加上@EnableFeignClients 注解

    复制代码

    @SpringBootApplication
    @EnableFeignClients
    public class FeignApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FeignApplication.class, args);
        }
    }

    复制代码

     

  2. 定义Feign client(feign client支持继承)

    @FeignClient("hello-service")
    public interface HelloClient extends BaseHelloClient{
    
        @RequestMapping("hello/param")
        String hello(@SpringQueryMap QueryParam param);
    }

     

  3. 调用Feign client

    复制代码

    @RestController
    public class FeignController {
    
        @Autowired
        private HelloClient helloClient;
    
        @RequestMapping("feign")
        public String feignTest(){
            return "调用Hello-service返回:" + helloClient.hello();
        }
    
        @RequestMapping("feign/param")
        public String feignTestParam(QueryParam param) {
            return "调用Hello-service返回:" + helloClient.hello(param);
        }
    }

    复制代码

     

依次启动三个项目,调用http://localhost:8083/feign 能正常返回调用hello-service的结果。

 本示例项目还通过@SrpingQueryMap 注解实现了Feign对 pojo用于GET请求参数的支持。如果不加@SrpingQueryMap, 则pojo参数是无法通过Feign client传递的,可去掉注解自行验证下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值