通常我们在使用openfeign发起服务调用时,需要同步等待调用结束。某些场景下,我们需要实现异步调用。
1、使用java8 的 CompletableFuture 异步工具
@ResourceOauthFeign oauthFeign;@GetMapping("/get")public Object get() {CompletableFuture<Object> completableFuture = CompletableFuture.supplyAsync(() -> {return oauthFeign.openFeignApi();});return completableFuture;}
RequestContextHolder中是将请求信息放入ThreadLocal中的,只能取到同一个线程的数据。
2、使用RequestContextHolder 获取主线程中的header信息
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
在异步线程内部设置 RequestContextHolder.setRequestAttributes(attributes);
CompletableFuture<T> future1 = CompletableFuture.supplyAsync(() -> {//openfeign的调用return feign.remoteCall();
},executor);CompletableFuture<T> future2 = CompletableFuture.supplyAsync(() -> {//openfeign的调用return feign.remoteCall();
},executor);CompletableFuture.allOf(future1,future2).join();.....
//获取主线程的请求信息
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();CompletableFuture<T> future1 = CompletableFuture.supplyAsync(() -> {//将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败RequestContextHolder.setRequestAttributes(attributes);//openfeign的调用return feign.remoteCall();
},executor);CompletableFuture<T> future2 = CompletableFuture.supplyAsync(() -> {//将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败RequestContextHolder.setRequestAttributes(attributes);//openfeign的调用return feign.remoteCall();
},executor);CompletableFuture.allOf(future1,future2).join();.....
3、全局设置(未验证)
1. 定义一个Feign RequestInterceptor拦截器:
java
public class RequestContextInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {ServletRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();if (requestAttributes != null) {RequestContextHolder.setRequestAttributes(requestAttributes, true);}}
} 2. 在FeignClient上添加配置,使用该拦截器:
java
@FeignClient(name="hello", configuration = HelloConfiguration.class)
public interface HelloClient {// ...
}public class HelloConfiguration { @Beanpublic RequestInterceptor requestContextInterceptor() {return new RequestContextInterceptor();}
}