敞开生长之旅!这是我参与「日新计划 12 月更文挑战」的第4天,点击查看活动概况
庾信平生最萧条,老年诗赋动江关
欢迎重视【架构染色】沟通学习
开篇
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
publicclassFeignApplication{
publicstaticvoidmain(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
)
publicinterfaceTestService{
@RequestMapping(value="/getError/{id}",method=RequestMethod.GET)
publicStringgetError(@RequestParam("id")Integerid);
@RequestMapping(value="/get1",method=RequestMethod.GET)
publicStringget1();
@RequestMapping(value="/get2/{param}",method=RequestMethod.GET)
publicStringget2(@RequestParam("param")Stringparam);
@RequestMapping(value="/post1",method=RequestMethod.POST)
publicFeignDemopost1(@RequestBodyFeignDemodemo);
1.4 编写对应的服务端
@RestController
@RequestMapping("/feign/server")
publicclassFeignServerController{
@GetMapping("/get1")
publicStringget1(){
return"get1";
}
@GetMapping("/get2/{para}")
publicStringget2(@PathVariable("para")Stringpara){
returnpara;
}
@PostMapping("/post1")
publicFeignDemopost1(@RequestBodyFeignDemodemo){
returndemo;
}
}
publicclassFeignDemo{
privateStringname;
privateIntegerage;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
@Override
publicStringtoString(){
return"FeignDemo{"+
"name='"+name+'''+
",age="+age+
'}';
}
}
1.5 调用 FeignClient
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes={FeignApplication.class},webEnvironment=SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("dev,feign")
publicclassFeignClientTest{
@Autowired
privateTestServicetestService;
@Test
publicvoidtestFallback(){
testService.getError(1);
}
@Test
publicvoidtestGet1(){
System.out.println(testService.get1());
System.out.println(testService.get2("abc"));
System.out.printf("..");
FeignDemofeignDemo=newFeignDemo();
feignDemo.setName("name");
feignDemo.setAge(1);
System.out.println(testService.post1(feignDemo));
}
@Component
publicclassDefaultFallbackimplementsTestService{
@Override
publicStringgetError(@RequestParam("id")Integerid){
return"";
}
@Override
publicStringget1(){
returnnull;
}
@Override
publicStringget2(Stringparam){
returnnull;
}
@Override
publicFeignDemopost1(FeignDemodemo){
returnnull;
}
}
}
二、怎么切换 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
publicclassFooConfiguration{
@Bean
Logger.LevelfeignLoggerLevel(){
returnLogger.Level.FULL;
}
}
这个一看即懂,不再废话。
四、怎么实现数据紧缩
能够分别对 HTTP 通讯的request
和response
设置是否启用 GZIP 紧缩,装备办法如下:
feign:
compression:
request:
enabled:true
mime-types:text/xml,application/xml,application/json#装备紧缩支撑的MIMETYPE
min-request-size:2048#装备紧缩数据大小的下限
response:
enabled:true#装备呼应GZIP紧缩
五、FeignClient 的装备以及装备的优先级机制
有 2 种途径设置 FeignClient 的装备,经过自定义装备类来设置装备和在装备文件中设置,其间装备文件方法有点特别,它里边能够指定大局装备对一切 FeignClient 有用,也能够为特定名称的 FeignClient 设置专属的装备。
5.1 经过自定义装备类来定制装备
实现一个装备类
publicclassTestConfiguration{
@Bean
Logger.LevelfeignLoggerLevel(){
returnLogger.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
retryer:com.example.SimpleRetryer
requestInterceptors:
-com.example.FooRequestInterceptor
-com.example.BarRequestInterceptor
decode404:false
encoder:com.example.SimpleEncoder
decoder:com.example.SimpleDecoder
5.4 理解装备的优先级与拦截器的追加准则
从org.springframework.cloud.openfeign.FeignClientFactoryBean#configureFeign
中能够确认以上 3 种装备的优先级:
configureUsingConfiguration(context,builder);//1
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()),builder);//2
configureUsingProperties(properties.getConfig().get(this.contextId),builder);//3
- 第 1 类为经过自定义装备类来指定装备
- 第 2 类为在装备文件中的
feign.client.config.default.xxx
设置大局装备 - 第 3 类为在装备文件中的
feign.client.config.feignName.xxx
设置专属装备
5.4.1 优先级的作用
装备文件里的专属装备-掩盖->装备文件里的大局装备-掩盖->装备类的装备
5.4.2 追加的准则
RequestInterceptor
是拦截器,能够在发送前做一些处理,比方一致添加header
信息。每一类中的requestInterceptors
能够存储多个拦截器,拦截器并非掩盖的作用,而是链式追加的作用;从履行顺序来看优先级是:1 > 2 > 3,即先履行装备类中指定的拦截器,然后是装备文件中指定的大局拦截器,最后是装备文件中指定的专属拦截器。
需特别注意:RequestInterceptor
的实现类(例如 RI-A,RI-B)上假如添加了@Component
注解,就都会被扫描识别到,并被追加到第一类的requestInterceptors
列表中;倘若不小心 RI-A 还在第 2 类中又被指定了,则还会将拦截器 RI-A 追加在第二类的requestInterceptors
列表中,结果是会 RI-A 总计会履行 2 次;若也在第三类中指定 RI-A,则 RI-A 也在其列表中追加,结果是 RI-A 总计会履行 3 次。
5.4.3 拦截器的作用验证
以一个实例来验证阐明作用
- 自定义三个 RequestInterceptor
classFeignInterceptorimplementsRequestInterceptor{
@Override
publicvoidapply(RequestTemplaterequestTemplate){
requestTemplate.header("user","myuser1");
requestTemplate.header("password","mypassword");
}
}
classFeignInterceptor1implementsRequestInterceptor{
@Override
publicvoidapply(RequestTemplaterequestTemplate){
requestTemplate.header("user1","myuser1");
requestTemplate.header("password1","mypassword1");
}
}
classFeignInterceptor2implementsRequestInterceptor{
@Override
publicvoidapply(RequestTemplaterequestTemplate){
requestTemplate.header("user2","myuser2");
requestTemplate.header("password2","mypassword2");
}
}
- @FeignClient 中指定一个
@FeignClient(
name="test-service",
url="http://localhost:8080/feign/server/",
configuration={FeignInterceptor.class,TestConfiguration.class},
fallback=TestService.DefaultFallback.class
)
- 装备中指定 2 个
default
指定了一个,test-service
里指定一个
feign:
httpclient:
enabled:true
okhttp:
enabled:true
client:
config:
default:
connectTimeout:5000
readTimeout:5000
#loggerLevel:none
requestInterceptors:
-com.zto.titans.test.feign.service.FeignInterceptor1
test-service:
#loggerLevel:basic
requestInterceptors:
-com.zto.titans.test.feign.service.FeignInterceptor2
logging:
level:
com.zto.titans.test.feign.service.TestService:DEBUG
依据追加逻辑,终究履行的顺序是:
- FeignInterceptor
- FeignInterceptor1
- FeignInterceptor2
总结
本篇首要介绍 SpringBoot 中要玩转 Feign 需要把握的如添加 pom 依靠、客户端注解启用、切换底层 HttpClient、装备数据紧缩、调整日志等级、定制装备、装备的优先级机制、添加拦截器以及拦截器的追加机制等常识,以实例 + 作用的方法帮读者高效全面并深化的理解它们。
最后说一句(请重视,莫错过)
假如这篇文章对您有协助,或者有所启发的话,欢迎重视公众号【 架构染色 】进行沟通和学习。您的支撑是我坚持写作最大的动力。
求一键三连:重视、点赞、转发。