基礎實現
requestInterceptor 實現類中添加信息
public class NativeFeignConf {
@Bean
public RequestInterceptor getRequestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
HttpServletRequest req=servletRequestAttributes.getRequest();
Map<String,Collection<String>> headerMap=new HashMap();
//獲取你需要傳遞的頭信息
String myHeaderVal=req.getHeader("myHeader");
headerMap.put("myHeader",Arrays.asList(myHeaderVal));
//feign請求時,便可攜帶上該信息
requestTempalte.headers(headerMap);
}
}
feign加入該config
@FeignClient(
value="target-service",
configuration=NativeFeignConf.class //加入該配置
)
public interface MyFeign(){
...
}
開啟 Hystrix 的情況下
開啟hystrix后,feign請求,會運行在hystrix管理的另一線程下。
所以RequestContextHolder.currentRequestAttributes()
無法獲取值。
解決方法:
創建一個自定義的hystrix 線程策略, 將servletRequestAttributes
傳入新線程中,並賦給RequestContextHolder
:
public class MyHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy{
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable){
ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return new Callable<T>() {
@Override
public T call() throws Exception {
try {
if (null != servletRequestAttributes) {
RequestContextHolder.setRequestAttributes(servletRequestAttributes);
}
return callable.call();
}finally {
RequestContextHolder.resetRequestAttributes();
}
}
};
}
}
注冊該策略
@Configuration
public class HystrixConfig{
@PostConstruct
public void init(){
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new MyHystrixConcurrencyStrategy()
)
}
}
結束。