OpenFeign学习(七):Spring Cloud OpenFeign的使用

说明

通过之前的几篇博文,我简单介绍了OpenFeign的使用及其工作原理。OpenFeign的易用性和扩展性让人印象深刻。接下来,我将继续学习Spring是如何对OpenFeign进行集成支持,使其在Spring Cloud 微服务体系中发挥着重要的作用。在本篇博文中,我将结合官方文档介绍Spring Cloud OpenFeign,了解其基本使用方式及功能特性。

进行服务间的调用无外乎HTTP请求或者RPC调用,在Spring Cloud 微服务体系中也支持了这两种方式。分别是以HTTP请求为基础的Spring Cloud OpenFeign 和阿里的dubbo。Spring Cloud OpenFeign 则是以OpenFign为基础,通过自动装配将其集成到Spring Boot应用中,纳入到Spring体系中。

通过官方文档我们可以初步了解Spring Cloud对OpenFeign做了那些改造支持。

Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.

可以看到Spring Cloud添加了对Spring MVC注解的支持和Spring Web使用的HttpMessageConverters, 并且集成了Ribbon 和 Eureka,提供了可以进行负载均衡了Http Client。

接下来,通过简单项目介绍如何使用Spring Cloud OpenFeign。

正文

快速上手

首先引入Spring Cloud OpenFeign 依赖,同时因为基于Eureka的服务注册发现,还要引入Eureka-Client 依赖。基于Spring Boot 2.1.14版本:

<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>

引入后,在项目启动类分别加上@EnableDiscoveryClient和@EnableFeignClients注解:

@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class Feign2ClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(Feign2ClientApplication.class, args);
	}

}

在application.yml中配置项目名称,端口和注册中心Eureka地址:

spring:
  application:
    name: feign2-client

server:
  port: 2003
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1001/eureka/

创建服务接口,使用@FeignClient注解:

@FeignClient(value = "feign2")
public interface Feign2Service {
    
}

至此,OpenFeign的服务已经配置完毕,通过@Autowired自动注入进行服务调用。

@Autowired
private Feign2Service feign2Service;

可以看到与之前OpenFeign的使用方式相比,我们不再需要使用其他注解配置,不用进行手动创建Feign Client 直接使用SpringMVC的注解, @FeignClient注解即可。同时,Spring Cloud OpenFeign 也支持了手动创建Feign Client,这种方式与OpenFeign相似,这里不再赘述,更多请看官方文档。

在@FeignClient注解的value值表示client名称,该名称被用来创建Ribbon load-balancer或者 Spring Cloud LoadBalancer 。负载均衡器通过该名称进行服务端物理地址的获取,如果项目是eureka-client,则通过eureka注册中心进行服务地址解析。

同时,如果项目没有使用eureka注册中心,@FeignClient注解也支持通过配置url参数来指定服务端的url。同时,文档提到也可以使用SimpleDiscoveryClient,并配置服务地址列表。

If you don’t want to use Eureka, you can simply configure a list of servers in your external configuration using SimpleDiscoveryClient.

没有eureka注册中心,通过url指定服务地址:

@FeignClient(value = "feign2", url = "http://localhost:2003")
public interface Feign2Service {

}

文档提到,为了保持向后兼容性,Rabbion作为默认的负载均衡器实现。但是由于Spring Cloud Netfix Ribbon项目已经进入维护状态,官方建议使用Spring Cloud LoadBalancer进行替代。可以设置spring.cloud.loadbalancer.ribbon.enabled 值为false进行配置。

自定义配置

先通过文件上传示例代码来了解如何修改Spring Cloud OpenFeign的默认配置:

在OpenFeign的feign-form项目中,我们了解了如何实现表单提交,主要是配置Encoder。在Spring中,我们需要配置SpringFormEncoder。

这里不需要引入额外的依赖,在spring-cloud-starter-openfeign依赖中,已经引入了feign-java8依赖,该依赖包含了feign-form和feign-form-spring。

@FeignClient(value = "feign2", configuration = Feign2Service.MultipartSupportConfig.class)
public interface Feign2Service {

    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String handleFileUpload(@RequestPart(value = "file") MultipartFile file);

    @Configuration
    class MultipartSupportConfig{
        @Bean
        public SpringFormEncoder feignFormEncoder(){
            return new SpringFormEncoder();
        }
    }
}

可以看到,先配置生成了SpringFormEncoder的bean对象,然后在@FeignClient注解中配置configuration值来修改默认Encoder。
这里使用的并不是spring标准的encoder配置,标准配置请看文档 feign-form 或者这篇博文《SpringCloud Feign Decoder》

通过文档我们可以了解到,Spring Cloud Netflix为feign提供了一些默认配置:

  • Decoder : ResponseEntityDecoder (包含了一个SpringEncoder)
  • Encoder : SpringEncoder
  • Logger : Slf4jLogger
  • Controct : SpringMvcControct
  • Feign.Builder : HystrixGeign.Builder
  • Client : 如果Ribbon可用则为LoadBalancerFeignClient对象,否则若Spring Cloud Balancer可用,则使用FeignBlockingLoadBalancerClient对象,两个都不可用时,则使用默认的feign client。

注意,spring-cloud-starter-openfeign依赖已经同时引入了spring-cloud-starter-netflix-ribbon 和 spring-cloud-starter-loadbalancer。

对于OpenFeign的默认Client : OkHttpClient和ApacheHttpClient,可以通过设置feign.okhttp.enabled 或 feign.httpclient.enabled 值为true进行启用。同时也可以自定义HttpClient。

在之前OpenFeign的使用介绍中,我们了解到OpenFeign有默认的重试器Retryer和对QueryMap的支持。但是Spring Cloud OpenFeign并没有对以下配置进行默认实现:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection
  • SetterFactory
  • QueryMapEncoder

通过以上文件传输方法配置可知,Spring Cloud OpenFeign提供了在@FeignClient注解中设置configuration值来覆盖默认配置的方法。对此我们可以通过该方式来配置以上自实现的Retryer, Interceptor, Logger.Level等。

@Configuration
class Config{
    @Bean
    public Retryer retryer() {
        return new MyRetryer();
    }

    @Bean
    public RequestInterceptor interceptor() {
        return new RequestHeaderInterceptor();
    }
    
    @Bean
    public Logger.Level level() {
        return Logger.Level.FULL;
    }
}


@FeignClient(value = "feign2", configuration = Feign2Service.Config.class)
public interface Feign2Service {
 
}

同时,我们也可以通过配置文件的方式对Feign进行配置,在application.yml中进行一下配置:

feign:
  client:
    config:
      feign2:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
        encoder: feign.form.spring.SpringFormEncoder
        requestInterceptors:
          - com.example.feign2.interceptor.RequestHeaderInterceptor

注意,config下级为对应feign的名称

对于所有Feign的默认配置,可以像以上展示的那样通过在@EnableFeignClients注解中设置defaultConfiguration值进行配置,又或者通过配置文件,将config下级对应feign的名称设置为default

如果同时在注解中设置了Configuration 对象 和在配置文件中进行了配置,此时配置文件的属性值会覆盖注解中的配置。如果想改变此优先级,可以设置feign.client.default-to-properties值为false。

对于OpenFeign日志的支持,在只有log level为debug时,才会输出日志。因此需要在配置文件中设置对应类的日志等级:

logging:
  level:
    com:
      example:
        feign2:
          service: debug

关于日志等级的分类,在之前的博文中我已经介绍过,在此不再赘述。

关于更多了Spring Cloud OpenFeign的默认配置值,请看文档Common application properties

@QueryMap

在之前OpenFeign介绍中,我们已经知道OpenFeign使用@QueryMap注解将POJO转换为GET请求参数。但是Spring Clound OpenFeign 并不支持该注解,因为它缺少Value属性。

为此,Spring Cloud OpenFeign提供了一个等效的注解@SpringQueryMap,该注解可以将一个POJO或者是Map参数转换为请求参数。

public class User {

    private String uname;
    private String pwd;
    
    ...getter setter
}


@FeignClient(value = "feign2")
public interface Feign2Service {
    @GetMapping("/hi")
    String hi(@SpringQueryMap User user);
}

与@QueryMap注解一样,会将POJO的参数名称或者Map的key值作为请求的参数名称。若需要改动,则可以自实现QueryMapEncoder bean。

至此,对Spring Cloud OpenFeign的简单使用及配置已经介绍完毕,接下来我将继续对Sprig Cloud OpenFeign 其他功能特性进行学习总结。


参考资料:
https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.2.3.RELEASE/reference/html/#feign-querymap-support

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值