Spring Cloud OpenFign简介

    xiaoxiao2025-07-22  17

    原文

    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. 实现客户端

    接下来,我们需要将@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.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.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上获得。

    最新回复(0)