SpringBoot 使用 Feign 简明一体化指南
开篇
Feign 是声明式、模板化的 HTTP 客户端, 可以帮助我们更快捷、优雅地调用 HTTP API;Spring Cloud 为 Feign 添加了 Spring MVC 的注解支持,并整合了 Ribbon 和 Eureka 来为使用 Feign 时提供负载均衡;在 Spring Cloud 中使用 Feign 是非常容易的。
本篇主要介绍 SpringBoot 中要玩转 Feign 需要掌握的如添加 pom 依赖、客户端注解启用、切换底层 HttpClient、配置数据压缩、调整日志级别、定制配置、配置的优先级机制、增加拦截器以及拦截器的追加机制等知识。
一、使用 Feign 的示例
1.1 添加依赖
<dependencies> <!--openfein的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.3.RELEASE</version> </dependency> </dependencies> 复制代码
1.2 启用 Feign
在 SpringBoot 的启用类上添加注解@EnableFeignClients
,@EnableFeignClients
用于开启 Feign,会自动扫描@FeignClient
标注的 FeignClient 接口。
@SpringBootApplication @EnableFeignClients @EnableWeb public class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class,args); } } 复制代码
1.3 编写 FeignClient 接口
@FeignClient( name = "demo-service", url = "http://localhost:8080/feign/server/", configuration = FeignInterceptor.class, fallback = TestService.DefaultFallback.class ) public interface TestService { @RequestMapping(value = "/getError/{id}", method = RequestMethod.GET) public String getError(@RequestParam("id") Integer id); @RequestMapping(value = "/get1", method = RequestMethod.GET) public String get1(); @RequestMapping(value = "/get2/{param}", method = RequestMethod.GET) public String get2(@RequestParam("param") String param); @RequestMapping(value = "/post1", method = RequestMethod.POST) public FeignDemo post1(@RequestBody FeignDemo demo); 复制代码
1.4 编写对应的服务端
@RestController @RequestMapping("/feign/server") public class FeignServerController { @GetMapping("/get1") public String get1() { return "get1"; } @GetMapping("/get2/{para}") public String get2(@PathVariable("para") String para){ return para; } @PostMapping("/post1") public FeignDemo post1(@RequestBody FeignDemo demo) { return demo; } } 复制代码
public class FeignDemo { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "FeignDemo{" + "name='" + name + ''' + ", age=" + age + '}'; } } 复制代码
1.5 调用 FeignClient
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = {FeignApplication.class},webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @ActiveProfiles("dev,feign") public class FeignClientTest { @Autowired private TestService testService; @Test public void testFallback(){ testService.getError(1); } @Test public void testGet1(){ System.out.println(testService.get1()); System.out.println(testService.get2("abc")); System.out.printf(".."); FeignDemo feignDemo = new FeignDemo(); feignDemo.setName("name"); feignDemo.setAge(1); System.out.println(testService.post1(feignDemo)); } @Component public class DefaultFallback implements TestService { @Override public String getError(@RequestParam("id") Integer id){ return ""; } @Override public String get1() { return null; } @Override public String get2(String param) { return null; } @Override public FeignDemo post1(FeignDemo demo) { return null; } } } 复制代码
二、如何切换 Client
Feign 中自带的是 HttpURLConnection,这个 client 健壮性差,可替换为成熟的 Apache HttpClient 或 OkHttp 来进行网络请求。
2.1 使用 Apache 的 HTTP Client
使用 Apache 的 httpclient
替换 Feign 中默认的 client。
2.1.1 添加依赖
<!--httpclient的依赖,因为选择了使用httpclient--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> <version>10.4.0</version> </dependency> 复制代码
2.1.2 配置启用
配置中添加如下信息,表示启用httpclient
。
feign: httpclient: enabled: true 复制代码
2.2 使用 OkHttp
2.2.1 添加依赖
在 Feign 中使用OkHttp
作为网络请求框架,则只需要在 pom 文件中加上feign-okhttp
的依赖,代码如下:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>10.2.0</version> </dependency> 复制代码
2.2.2 配置启用
feign: okhttp: enabled: true 复制代码
三、如何修改日志级别
在发送和接收请求的时候,其内部将日志的打印输出定义成了四个等级,对应的详情如下:
级别 | 说明 |
NONE | 不做任何记录 |
BASIC | 仅记录请求方法和 URL 以及响应状态代码和执行时间 |
HEADERS | 记录基本信息以及请求和响应标头 |
FULL | 记录请求和响应的标题,正文和元数据 |
3.1 通过配置文件修改日志级别
注意需要指定接口的全限定名
logging: level: com.zto.titans.test.feign.service.TestService : DEBUG 复制代码
3.2 通过配置类修改日志级别
@Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } } 复制代码
这个一看即懂,不再废话。
四、如何实现数据压缩
可以分别对 HTTP 通信的request
和response
设置是否启用 GZIP 压缩,配置方法如下:
feign: compression: request: enabled: true mime-types: text/xml,application/xml,application/json # 配置压缩支持的MIME TYPE min-request-size: 2048 # 配置压缩数据大小的下限 response: enabled: true # 配置响应GZIP压缩 复制代码
五、FeignClient 的配置以及配置的优先级机制
有 2 种途径设置 FeignClient 的配置,通过自定义配置类来设置配置和在配置文件中设置,其中配置文件方式有点特殊,它里边可以指定全局配置对所有 FeignClient 有效,也可以为特定名称的 FeignClient 设置专属的配置。
5.1 通过自定义配置类来定制配置
实现一个配置类
public class TestConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } } 复制代码
将配置类 TestConfiguration
指定给configuration
。
@FeignClient( name = "test-service", configuration = {FeignInterceptor2.class,TestConfiguration.class} ) 复制代码
5.2 在配置文件中设置全局配置
feign.client.config.default.xxx ,这个default意为
全局的配置属性。
feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 loggerLevel: basic 复制代码
5.3 在配置文件中设置专属配置
feign.client.config.feignName.xxx , 给名字为feignName的FeignClient
指定专属的配置。
feign: client: config: feignName: connectTimeout: 5000 readTimeout: 5000 loggerLevel: full errorDecoder: com.example.SimpleErrorDecoder上一篇: MySQL 8.0 新增功能:解释分析 SQL 执行过程
下一篇: [MySQL] MySQL中的原子更新操作:如何模拟 MongoDB 的 "find_one_and_update