自定义单个接口配置
再不改变全局配置怎么指定单个接口feign的配置呢
官网提供了一个方法,自定义FeignClientConfigurer 注入容器,在@FeignClient的属性configuration 指定自定义的配置即可。
我们看一下feign默认的配置
这是feign的默认重试
具体实现:
具体怎么使用要看SynchronousMethodHandler类
实现了MethodHandler接口 重写invoke方法
注意方法中catch的异常是 RetryableException, 这是由executeAndDecode中在客户端发出请求时抛出的异常
抛出自定义异常在invoke方法catch调用Retryer的continueOrPropagate方法进行重试处理;
大佬又让我涨了一波见识!
配置文件配置:
feign:
client:
config:
contextId:
readTimeout:2000
connectTimeout:1000
最终映射到FeignClientProperties的config中
多线程feign传递请求头参数
@Configuration
@Slf4j
public class FeignConfig implements RequestInterceptor {
private static String[] allowHeaders = {"user", "token", "x-request-id", "build-version", "longitude", "latitude", "city-code", "device-id"};
/**
* 往下一级传递的header
*/
private static final Set<String> PASS_HEADERS = new HashSet<>(Arrays.asList(allowHeaders));
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 防止子线程拿不到 或者 请求头没有传, 从MDC中获取
String requestIdKey = "X-Request-Id";
String buildVersion = "Build-Version";
String requestId = MDC.get(requestIdKey);
String version = MDC.get(buildVersion);
if (StringUtils.isNotBlank(requestId)) {
requestTemplate.header(requestIdKey, StringUtils.trimToEmpty(requestId));
}
if (StringUtils.isNotBlank(version)){
requestTemplate.header(buildVersion, StringUtils.trimToEmpty(version));
}
if (attributes == null) {
log.warn("requestTemplate attributes is null");
return;
}
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames == null) {
return;
}
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
String value = request.getHeader(key);
if (PASS_HEADERS.contains(key.toLowerCase()) && value != null) {
requestTemplate.header(key, value);
}
}
}