概述
文章目录
- SpringCloud 分布式基础篇
- 一、openfeign是什么?
- 二、快速开始
- 1. 引入依赖
- 2. 调用者服务创建接口
- 3.启用openfeign
- 三、传递token
- 四、异步丢失上下文
- 1.RequestContextHolder
- 2. 异步调用
- 3.解决方式
- 五、传递文件流
SpringCloud 分布式基础篇
一、openfeign是什么?
openfeign是一个声明式的Web服务客户端。它使编写Web服务客户端更容易。
为了简化开发,OpenFeign整合了Ribbon和Hystrix,并且可以不通过RestTemplate就可以调用其他服务。
本章暂时不介绍Ribbon和Hystrix。
二、快速开始
1. 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 调用者服务创建接口
@FeignClient(“stores”) 调用nacos服务中心中stores服务 也可以用path参数指定相同部分uri@FeignClient(value = "stores", path = "/api/demo/stores")
@FeignClient("stores")
public interface StoreClient {
//该方法为stores服务暴露的接口签名,即stores服务controller层的每个接口头部代码
//如果FeignClient指定path,则value直接写后面部分即可,即 value = "/stores"
@RequestMapping(method = RequestMethod.GET, value = "/api/demo/stores")
List<Store> getStores();
@RequestMapping(method = RequestMethod.GET, value = "/api/demo/stores")
Page<Store> getStores(Pageable pageable);
@RequestMapping(method = RequestMethod.POST, value = "/api/demo/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
}
3.启用openfeign
在调用者的启动文件添加注解@EnableFeignClients
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
三、传递token
- openfeign调用时会丢失请求头。
- openfeign请求服务时会自动创建一个新的请求,虽然最开始的入口请求会有请求头,但是当openfeign实际触发的时候会新建一个请求,这个请求是不带任何header信息的。
- openfeign在创建请求对象的过程中会查询该服务是否有拦截器,拦截器会对请求对象进行丰富,那么答案就在这里
在调用方服务添加拦截器
/**
* 同步token 如果使用了熔断器,暂时配置关闭feign.hystrix.enabled=false 否则取不到attributes.
*
* @author: Mr.wanter
* @since 2021-04-06 14:08
*/
@Configuration
public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
if (null != request) {
//获取请求头
String token = request.getHeader("token");
if (null != token) {
token = StringUtils.removeStart(token, "Bearer ");
//设置新请求的请求头
template.header("token", new String[]{token});
}
}
}
}
}
四、异步丢失上下文
当我们使用异步处理openfeign请求时,我们会发现拦截器中ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
为空。
1.RequestContextHolder
RequestContextHolder为spring为我们提供的上下文工具类。
查看源码我们发现,他的底层是基于ThreadLocal实现的。即获取的数据为主线程的上下文信息。
public abstract class RequestContextHolder {
private static final boolean jsfPresent = ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");
2. 异步调用
任何异步调用方式都是以开启新线程的方式进行异步调用。new Thread()
、CompletableFuture.runAsync()
等
3.解决方式
- 在主线程获取一次上下文
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
异步处理中将主线程的上下文添加到异步线程中
RequestContextHolder.setRequestAttributes(attributes);
- 线程共享:在主线程执行
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(),true);
true表示子线程共享主线程上下文。
说明:这种共享方式适合用于主线程等待子线程完成任务后再结束的情况,否则主线程先于子线程结束时主线程的request销毁,子线程还是共享不了主线程的request属性。
五、传递文件流
参考:
OpenFeign实现微服务间的文件上传
OpenFeign实现微服务间的文件下载
最后
以上就是深情鸡为你收集整理的第二章 SpringCloud远程服务调用之openfeignSpringCloud 分布式基础篇一、openfeign是什么?二、快速开始三、传递token四、异步丢失上下文五、传递文件流的全部内容,希望文章能够帮你解决第二章 SpringCloud远程服务调用之openfeignSpringCloud 分布式基础篇一、openfeign是什么?二、快速开始三、传递token四、异步丢失上下文五、传递文件流所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复