Feign
文章目录
- 1 什么是Feign
- 2 整合OpenFeign
- 2.1 引入依赖
- 2.2 Feign的接口
- 3 Openfeign自定义配置
- 3.1 日志配置
- 3.2 超时时间配置
- 3.3 自定义拦截器
1 什么是Feign
Feign是Nettfix开发的声明式,模板化的HTTP客户端,可帮助我们更加便捷、优雅地调用HTTP API。
Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便。
调用方法就像调用本地方法一样,跟Bubbo类似
2 整合OpenFeign
- 引入依赖
- 创建要调用的服务对应的接口
2.1 引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>4.1.0</version>
</dependency>
2.2 Feign的接口
user服务调用order服务,feign对应的是被调用方的controller,
- user服务中的feign接口
import com.wzw.entity.UserEntity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;/*** name 对应被调用的服务注册到nacos上的服务名称* path 对应服务中的controller路径*/
@FeignClient(name="order-server",path = "/order")
public interface OrderFeignService {/*** @GetMapping 对应被调用的服务的controller的路径* 方法完全一致,只是没有方法体*/@GetMapping("/login")String login();@PostMapping("/add")String add(@RequestBody UserEntity userEntity);}
- user服务的controller
import com.alibaba.fastjson2.JSON;
import com.wzw.entity.UserEntity;
import com.wzw.feign.OrderFeignService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/user")
public class LoginController {@Resourceprivate OrderFeignService orderFeignService;@GetMapping("/feign_login")public String feignLogin(){return orderFeignService.login();}@PostMapping("/feign_add")public String feignAdd(@RequestBody UserEntity userEntity){return orderFeignService.add(userEntity);}}
-
user服务使用注解
@EnableFeignClients
-
测试
3 Openfeign自定义配置
3.1 日志配置
- 全局配置
feign的日志级别是debug,springboot的默认是info,需要在配置文件中修改日志级别,才能看到/*** 全局配置 @Configuration,所有调用都会打印* 局部配置 不使用@Configuration*/ @Configuration public class FeignConfig {/*** NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。* BASC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。* HEADERS:记录BASIC级别的基础上,记录请求和响应的header。.* FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。* @return*/@BeanLogger.Level feignLoggerLevel(){return Logger.Level.FULL;}}
logging:level:com.wzw.feign: debug
- 局部配置
- 配置类的方式
不使用@Configuration
想要哪个调用打印日志,就在具体的feign接口中,指定configuration的对象
@FeignClient(name="order-server",path = "/order",configuration = FeignConfig.class) public interface OrderFeignService { }
- 配置文件的方式
- 配置类的方式
3.2 超时时间配置
import feign.Request;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 全局配置*/
@Configuration
public class FeignConfig {@Beanpublic Request.Options options() {//连接超时时间,请求处理超时时间return new Request.Options(5000, 5000);}}
处理时间设置了五秒,设置睡眠六秒,报了超时错误
3.3 自定义拦截器
feign拦截器是作用在调用端到服务提供端之间的拦截器
- 创建拦截器
头部塞了一个request1,然后请求地址改成了add1
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class CustomInterceptor implements RequestInterceptor {Logger logger = LoggerFactory.getLogger(CustomInterceptor.class);@Overridepublic void apply(RequestTemplate requestTemplate) {logger.info("feign拦截器拦截到请求");requestTemplate.header("request1", "request111111111111111");requestTemplate.query("name", "zhangsan");requestTemplate.uri("/add1");}}
- 添加自定义拦截器
import com.wzw.interceptor.fegin.CustomInterceptor;
import feign.Logger;
import feign.Request;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 全局配置*/
@Configuration
public class FeignConfig {/*** NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。* BASC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。* HEADERS:记录BASIC级别的基础上,记录请求和响应的header。.* FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。* @return*/@BeanLogger.Level feignLoggerLevel(){return Logger.Level.FULL;}@Beanpublic Request.Options options() {//连接超时时间,请求处理超时时间return new Request.Options(5000, 5000);}/*** 自定义拦截器* @return*/@Beanpublic CustomInterceptor feignAuthRequestInterceptor(){return new CustomInterceptor();}}
- 测试
请求的是add,但是因为拦截器修改了路径,实际请求了add1