目录
2. Spring Cloud Alibaba快速整合OpenFeign
3. Spring Cloud Feign的自定义配置及使用
JAVA 项目中如何实现接口调用?
1)Httpclient
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富
的支持 Http 协议的客户端编程工具包,并且它支持 HTTP 协议最新版本和建议。HttpClient
相比传统 JDK 自带的 URLConnection,提升了易用性和灵活性,使客户端发送 HTTP 请求变
得容易,提高了开发的效率。
2)Okhttp
一个处理网络请求的开源项目,是安卓端最火的轻量级框架,由 Square 公司贡献,用于替代
HttpUrlConnection 和 Apache HttpClient。OkHttp 拥有简洁的 API、高效的性能,并支持
多种协议(HTTP/2 和 SPDY)。
3)HttpURLConnection
HttpURLConnection 是 Java 的标准类,它继承自 URLConnection,可用于向指定网站发送
GET 请求、POST 请求。HttpURLConnection 使用比较复杂,不像 HttpClient 那样容易使
用。
4)
RestTemplate
WebClient
RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便
捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
上面介绍的是最常见的几种调用接口的方法,我们下面要介绍的方法比上面的更简单、方便,
它就是 Feign。
1. 什么是Feign
Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及
WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。 Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了
Ribbon和Nacos,从而使得Feign的使用更加方便。
1.1 优势
Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验,开发者完全感知不
到这是远程方法,更感知不到这是个 HTTP 请求。它像 Dubbo 一样,consumer 直接调用接
口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。它解决了
让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布
式环境开发。
2. Spring Cloud Alibaba快速整合OpenFeign
1)引入依赖
<!-- openfeig 远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)编写调用接口+@FeignClient注解
package com.wang.openfeign;
import com.wang.config.FeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author wang fei
* @description:
* 开启Feign, 根据不同的url,传入不同的参
* name 指定调用rest接口所在的服务名称
* path 指定调用rest接口所在的Controller指定的@RequestMapping映射路径
* 局部配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类,configuration = FeignConfig.class
**/
@FeignClient(name = "stock-nacos",path = "/stock")
public interface OrderFeignService {
//声明需要调用rest接口对应的方法
@RequestMapping("/reduct")
String reduct();
@RequestMapping("/reduct2")
String reduct2();
}
3)调用端在启动类上添加@EnableFeignClients注解
4)发起调用,像调用本地方式一样调用远程服务
package com.wang.controller;
import com.wang.openfeign.OrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.controllter
* @Author: wang fei
* @CreateTime: 2023-01-16 16:48
* @Description: TODO
* @Version: 1.0
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderFeignService orderFeignService;
@GetMapping("/pay")
public String pay(){
String msg = orderFeignService.reduct();
System.out.println("小王支付成功" + msg);
return msg;
}
}
3. Spring Cloud Feign的自定义配置及使用
Feign 提供了很多的扩展机制,让用户可以更加灵活的使用。
3.1 日志配置
有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要
配置 Feign 的日志了,以此让 Feign 把请求信息输出来。
全局配置: 当使用@Configuration 会将配置作用所有的服务提供方 局部配置: 1. 通过配置类:如果只想针对某一个服务进行配置, 就不要加@Configuration 2. 通过配置文件
3.1全局配置: 当使用@Configuration 会将配置作用所有的服务提供方
1)定义一个配置类,指定日志级别
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
通过源码可以看到日志等级有 4 种,分别是:
- NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。
- BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及
执行时间。
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
- FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body
和元数据。
3.2局部配置,让调用的微服务生效,在
@FeignClient 注解中指定使用的配置类
方式1:通过配置类:如果只想针对某一个服务进行配置, 就不要加@Configuration
1)配置类:
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
//@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
@Bean
public CustomFeignInterceptor feignAuthRequestInterceptor(){
return new CustomFeignInterceptor();
}
}
2)接口:
package com.wang.openfeign;
import com.wang.config.FeignConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author wang fei
* @description:
* 开启Feign, 根据不同的url,传入不同的参
* name 指定调用rest接口所在的服务名称
* path 指定调用rest接口所在的Controller指定的@RequestMapping映射路径
* 局部配置,让调用的微服务生效,在@FeignClient注解中指定使用的配置类,configuration = FeignConfig.class
**/
@FeignClient(name = "stock-nacos",path = "/stock",configuration = FeignConfig.class)
public interface OrderFeignService {
//声明需要调用rest接口对应的方法
@RequestMapping("/reduct")
String reduct();
@RequestMapping("/reduct2")
String reduct2();
}
3)配置spring日志级别:
logging: level: com.wang.openfeign: debug #日志级别
补充:局部配置可以在yml中配置
对应属性配置类:
feign:
client:
config:
对应微服务名称
loggerLevel: FULL
方式2:通过配置文件(推荐)
feign:
client:
config:
stock-nacos:
loggerLevel: BASIC
效果截图:
4.自定义拦截器
我们openfeign实现RequestInterceptor接口定义自定义拦截器,在拦截器中完成相关业务。如下一个例子。
1)实现RequestInterceptor接口
package com.wang.intercptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.UUID;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.intercptor
* @Author: wang fei
* @CreateTime: 2023-01-20 15:53
* @Description: TODO
* @Version: 1.0
*/
public class CustomFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
/* TODO 自定义 feign 请求拦截器 业务逻辑 */
String access_token= UUID.randomUUID().toString();
requestTemplate.header("token",access_token);
System.out.println("请求拦截器feign自定义");
}
}
1)将自定义的拦截器配置
- 通过配置类配置
package com.wang.config;
import com.wang.intercptor.CustomFeignInterceptor;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @BelongsProject: SpringCloudAlibabaLearn
* @BelongsPackage: com.wang.config
* @Author: wang fei
* @CreateTime: 2023-01-20 15:26
* @Description: TODO
* @Version: 1.0
*/
/**
* 配置Feign的日志
* 注意: 此处配置@Configuration注解就会全局生效,如果想指定对应微服务生效,就不能配置
* @author 飞
*/
//@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
//自定义拦截器
@Bean
public CustomFeignInterceptor feignAuthRequestInterceptor(){
return new CustomFeignInterceptor();
}
}
- 通过配置文件配置
feign:
client:
config:
stock-nacos:
# loggerLevel: BASIC
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 10000
requestInterceptors[0]:
com.wang.interceptor.CustomFeignInterceptor #feign的拦截器自定义
5.超时时间配置
通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时
时间(ms),默认值是 2s;第二个是请求处理的超时时间(ms),默认值是 5s。
全局配置 :
@Configuration
public class FeignConfig {
@Bean
public Request.Options options() {
return new Request.Options(5000, 10000);
}
}
yml中配置 :
feign:
client:
config:
mall‐order: #对应微服务
# 连接超时时间,默认2s
connectTimeout: 5000
# 请求处理超时时间,默认5s
readTimeout: 10000