Spring Cloud OpenFign简介
原文链接:www.baeldung.com/spring-clou…
作者: baeldung
译者:Yunooa
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.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
此外,我们还需要添加spring-cloud-dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
我们可以 在Maven Central上找到最新版本的spring-cloud-starter-openfeign和spring-cloud-dependencies。
3.Feign 客户端
接下来,我们需要将@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:
- 解码器 - ResponseEntityDecoder,它包装SpringDecoder, 用于解码响应。
- Encoder - SpringEncoder,用于编码RequestBody。
- Logger - Slf4jLogger是Feign使用的默认记录器。
- Contract - SpringMvcContract,提供注释处理。
- Feign-Builder - 用于构造组件的HystrixFeign.Builder。
- 客户端 - LoadBalancerFeignClient或默认的Feign客户端。
4.1自定义配置
如果我们想要自定义一个或多个这些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.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
我们可以在Maven Central 找到最新版本的feign-okhttp和 feign -httpclient。
4.2使用属性配置
我们可以使用应用程序属性来配置Feign客户端,而不是使用@Configuration类,如application.yaml示例所示:
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
使用此配置,我们将应用程序中每个声明的客户端的超时设置为5秒,并将logger级别设置为basic。最后,我们可以创建配置,使用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文件中声明它:
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
或者,如果我们只想为包中的一个特定客户端启用日志记录,我们可以使用完整的类名:
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;
}
}
有四种日志记录级别可供选择:
- 无 - 没有记录,这是默认值。
- BASIC - 仅记录请求方法,URL和响应状态。
- 标题 - 将基本信息与请求和响应标头一起记录。
- 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上获得。