将 Spring RequestAttributes (RequestContextHolder) 传播到 Feign 配置 bean?
Propagate Spring RequestAttributes (RequestContextHolder) to Feign configuration beans?
我正在使用 Feign 配置 class,使用这样的注释声明;
@FeignClient(name = "${earfsdf}", configuration = FeignConf.class)
FeignConf 在这种情况下不是 Spring @Configuration,它纯粹是针对使用上述注释的 Feign 客户端。在 FeignConf 中,我声明了一个 RequestInterceptor bean;
@Bean
public RequestInterceptor requestInterceptor() {
这会被 Feign 正确拾取,当我在 Feign 客户端上发出请求时会调用它。
但是,我希望这个 RequestInterceptor bean 能够访问 Spring "RequestAttributes",我正在尝试使用 Spring 的 RequestContextHolder.getRequestAttributes()
似乎当我从 RequestInterceptor 中调用它时,它 returns 为空。有什么方法可以将 RequestAttributes 传播到 Feign RequestInterceptor 中以使其可用吗?
谢谢!
原来答案是使用 HystrixCallableWrapper,它允许您包装通过 Hystrix 的任务(我正在使用 Feign)
Hystrix 为 Feign 调用创建了一个新线程。可调用包装器在父线程上调用,因此您可以获取所需的所有上下文,将其传递给新的可调用对象,然后将上下文加载到在新线程上执行的可调用对象中。
public class ContextAwareCallableWrapper implements HystrixCallableWrapper {
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
Context context = loadContextFromThisThread();
return new ContextAwareCallable<>(callable, context);
}
public static class ContextAwareCallable<T> implements Callable<T> {
private final Callable<T> callable;
private Context context;
ContextAwareCallable(Callable<T> callable, Context context) {
this.callable = callable;
this.context = context;
}
@Override
public T call() throws Exception {
try {
loadContextIntoNewThread(context);
return callable.call();
} finally {
resetContext();
}
}
}
}
我正在使用 Feign 配置 class,使用这样的注释声明;
@FeignClient(name = "${earfsdf}", configuration = FeignConf.class)
FeignConf 在这种情况下不是 Spring @Configuration,它纯粹是针对使用上述注释的 Feign 客户端。在 FeignConf 中,我声明了一个 RequestInterceptor bean;
@Bean
public RequestInterceptor requestInterceptor() {
这会被 Feign 正确拾取,当我在 Feign 客户端上发出请求时会调用它。
但是,我希望这个 RequestInterceptor bean 能够访问 Spring "RequestAttributes",我正在尝试使用 Spring 的 RequestContextHolder.getRequestAttributes()
似乎当我从 RequestInterceptor 中调用它时,它 returns 为空。有什么方法可以将 RequestAttributes 传播到 Feign RequestInterceptor 中以使其可用吗?
谢谢!
原来答案是使用 HystrixCallableWrapper,它允许您包装通过 Hystrix 的任务(我正在使用 Feign)
Hystrix 为 Feign 调用创建了一个新线程。可调用包装器在父线程上调用,因此您可以获取所需的所有上下文,将其传递给新的可调用对象,然后将上下文加载到在新线程上执行的可调用对象中。
public class ContextAwareCallableWrapper implements HystrixCallableWrapper {
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
Context context = loadContextFromThisThread();
return new ContextAwareCallable<>(callable, context);
}
public static class ContextAwareCallable<T> implements Callable<T> {
private final Callable<T> callable;
private Context context;
ContextAwareCallable(Callable<T> callable, Context context) {
this.callable = callable;
this.context = context;
}
@Override
public T call() throws Exception {
try {
loadContextIntoNewThread(context);
return callable.call();
} finally {
resetContext();
}
}
}
}