Spring Cloud OpenFeign简介

原文

1. 概述

在本教程中,我们将描述 Spring Cloud OpenFeign一个用于Spring Boot应用程序的声明性REST客户端。
Feign使用可插入的注释支持更轻松地编写Web服务客户端,其中包括Feign注释和JAX-RS注释。
此外,Spring Cloud还增加了对Spring MVC注释的支持,并使用了与 Spring Web中使用的相同的 HttpMessageConverters。
并且,使用Feign的一个好处是我们不必编写任何用于调用服务的代码,除了接口定义。

2. 依赖性

首先,我们将首先创建一个Spring Boot Web项目,并将spring-cloud-starter-openfeign依赖项添加到我们的 pom.xml 文件中:

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
dependency>

此外,我们还需要添加spring-cloud-dependencies:

<dependencyManagement>
     <dependencies>
         <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>${spring-cloud.version}version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

我们可以 在Maven Central上找到最新版本的spring-cloud-starter-openfeign和spring-cloud-dependencies。

3. 实现客户端

接下来,我们需要将@EnableFeignClients添加 到我们的主类:

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

通过此注释,我们为声明它们是Feign客户端的接口启用组件扫描。
然后,我们使用@FeignClient注释声明一个Feign客户端:

@FeignClient(value = "jplaceholder", url = "https://jsonplaceholder.typicode.com/")
public interface JSONPlaceHolderClient {
 
    @RequestMapping(method = RequestMethod.GET, value = "/posts")
    List<Post> getPosts();
 
    @RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json")
    Post getPostById(@PathVariable("postId") Long postId);
}

在此示例中,我们已将客户端配置为从JSONPlaceHolder API读取 。
@FeignClient 注释中传递的value参数是必需的任意客户端名称,而使用url参数时,我们指定API基本URL。
此外,由于此接口是Feign客户端,我们可以使用Spring Web注释来声明我们想要访问的API。

4. 配置

现在,了解每个Feign客户端由一组可自定义的组件组成是非常重要的。
Spring Cloud使用我们可以自定义的FeignClientsConfiguration类为每个命名客户端按需创建一个新的默认设置, 如下一节所述。
上面的类包含这些bean:
Decoder - ResponseEntityDecoder,它包装SpringDecoder, 用于解码响应
Encoder - SpringEncoder,用于编码RequestBody
Logger - Slf4jLogger是Feign使用的默认记录器
Contract - SpringMvcContract,提供注释处理
Feign-Builder - 用于构造组件的HystrixFeign.Builder
Client - LoadBalancerFeignClient或默认的Feign客户端

4.1 自定义Bean配置

如果我们想要自定义一个或多个这些bean,我们可以使用@Configuration类覆盖它们,然后我们将其添加到FeignClient注释中:

@FeignClient(value = "jplaceholder",
  url = "https://jsonplaceholder.typicode.com/",
  configuration = MyClientConfiguration.class)
@Configuration
public class MyClientConfiguration {
    @Bean
    public OkHttpClient client() {
        return new OkHttpClient();
    }
}

在这个例子中,我们告诉Feign使用 OkHttpClient而不是默认的,以支持HTTP / 2。
Feign支持多个客户端用于不同的用例,包括 ApacheHttpClient,它会根据请求发送更多标头 - 例如,Content-Length,这是某些服务器所期望的。

为了使用这些客户端,我们不要忘记将所需的依赖项添加到我们的pom.xml文件中,例如:

<dependency>
    <groupId>io.github.openfeigngroupId>
    <artifactId>feign-okhttpartifactId>
dependency>
 
<dependency>
    <groupId>io.github.openfeigngroupId>
    <artifactId>feign-httpclientartifactId>
dependency>

我们可以在Maven Central 找到最新版本的feign-okhttp和 feign -httpclient。

4.2 使用属性配置

我们可以使用应用程序属性来配置Feign客户端,而不是使用@Configuration类,如此application.yml示例所示:

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

使用此配置,我们将应用程序中每个声明的客户端的超时设置为5秒,并将记录器级别设置为基本。

最后,我们可以创建配置,使用default作为客户端名称来配置所有@FeignClient 对象,或者我们可以为配置声明feign客户端名称:

feign:
  client:
    config:
      jplaceholder:

如果我们同时拥有@Configuration bean和配置属性,配置属性将覆盖@Configuration值。

5. 拦截器

添加拦截器是Feign提供的另一个有用的功能。

对于每个HTTP请求/响应,拦截器可以执行各种隐式任务,从身份验证到日志记录。

因此,在下面的代码片段中,让我们声明一个请求拦截器,为每个请求添加基本身份验证:

@Bean
public RequestInterceptor requestInterceptor() {
  return requestTemplate -> {
      requestTemplate.header("user", username);
      requestTemplate.header("password", password);
      requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
  };
}

另外,要将拦截器添加到请求链,我们只需要将此bean添加到我们的@Configuration类中,或者如前所述,在属性文件中声明它:

feign:
  client:
    config:
      default:
        requestInterceptors:
          com.baeldung.cloud.openfeign.JSONPlaceHolderInterceptor

6. Hystrix支持

Feign支持Hystrix,所以如果我们启用它,我们就可以实现回退模式。
使用回退模式,当远程服务调用失败而不是生成异常时,服务使用者将执行替代代码路径以尝试通过其他方式执行操作。
为了实现这一目标,我们需要在属性文件中启用Hystrix添加 feign.hystrix.enabled = true。
这允许我们实现在服务失败时调用的回退方法:

@Component
public class JSONPlaceHolderFallback implements JSONPlaceHolderClient {
 
    @Override
    public List<Post> getPosts() {
        return Collections.emptyList();
    }
 
    @Override
    public Post getPostById(Long postId) {
        return null;
    }
}

为了让Feign知道已经提供了回退方法,我们还需要在@FeignClient注释中设置我们的回退类:

@FeignClient(value = "jplaceholder",
  url = "https://jsonplaceholder.typicode.com/",
  fallback = JSONPlaceHolderFallback.class)
public interface JSONPlaceHolderClient {
    // APIs
}

7.记录
对于每个Feign客户端,默认情况下会创建一个记录器。

要启用日志记录,我们应该使用客户端接口的包名称在application.propertie文件中声明它 :

1
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
或者,如果我们只想为包中的一个特定客户端启用日志记录,我们可以使用完整的类名:

1
logging.level.com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient: DEBUG
请注意,Feign日志记录仅响应DEBUG级别。

我们可以为每个客户端配置的Logger.Level指示记录多少:

@Configuration
public class ClientConfiguration {
     
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.BASIC;
    }
}

有四种日志记录级别可供选择:

NONE - 没有记录,这是默认值
BASIC - 仅记录请求方法,URL和响应状态
HEADERS - 将基本信息与请求和响应标头一起记录
FULL - 记录请求和响应的正文,标题和元数据

8. 错误处理

Feign的默认错误处理程序ErrorDecoder.default始终抛出FeignException。

现在,这种行为并不总是最有用的。因此,要自定义抛出的Exception,我们可以使用CustomErrorDecoder:

public class CustomErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
 
        switch (response.status()){
            case 400:
                return new BadRequestException();
            case 404:
                return new NotFoundException();
            default:
                return new Exception("Generic error");
        }
    }
}

然后,正如我们之前所做的那样,我们必须 通过向@Configuration类添加bean来 替换默认的ErrorDecoder:

@Configuration
public class ClientConfiguration {
 
    @Bean
    public ErrorDecoder errorDecoder() {
        return new CustomErrorDecoder();
    }
}

9. 结论

在本文中,我们在一个简单的示例应用程序中讨论了Spring Cloud OpenFeign及其实现。
此外,我们已经了解了如何配置客户端,如何在我们的请求中添加拦截器,以及如何使用Hystrix和ErrorDecoder处理错误。
像往常一样,本教程中显示的所有代码示例都可以 在GitHub上获得。

你可能感兴趣的:(Java编程,Spring,Cloud,OpenFeign)