我正在开发一个使用Feign和OAuth2的spring cloud项目。项目中有一些耗时的操作,这些操作完成后会发送一些请求。为了获得更好的用户体验,这些操作被移到了异步方法中(使用@Async)。但是出现了一个问题。我将 OAuth2FeignRequestInterceptor 添加为 bean,并确保 Feign Client 可以在同步方法中正常工作(哪个线程在 RequestContextHolder 中具有正确的 RequestAttributes)。
@Configuration
public class SomeConfiguration{
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext, BaseOAuth2ProtectedResourceDetails resource){
return new OAuth2FeignRequestInterceptor(oAuth2ClientContext,resource);
}
}
但是如果我将这些操作移到异步方法中,就会抛出一个异常,即由于缺少RequestContext而无法创建scopedTarget.oauth2ClientContext。我搜索了stackoverflow.com并找到了一个解决方案: 如何在异步任务执行器中启用请求范围 使用 RequestContextListener bean 和这些代码,属于子线程的 RequestContextHolder 将填充父线程(请求线程)的 RequestAttributes。因为异步方法在调用 feign 客户端之前会花费一些时间,所以请求会在调用 feign 客户端之前得到响应。当请求得到响应时,RequestContextListener 将通过调用 RequestContextHolder.resetRequestAttributes();(RequestContextListener.java:76) 来重置 RequestContextHolder 中的 RequestAttributes,并使 RequestAttributes 中的请求处于非活动状态。当它完成耗时的任务并尝试通过 feign 客户端发送一些东西时,feign 客户端尝试从请求中获取 oAuth2ClientContext 并抛出异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: Cannot ask for request attribute - request is not active anymore!
我不确定 OAuth2FeignRequestInterceptor 在异步场景中从 RequestContext 检索授权信息是否合适。
感谢您阅读我的问题并希望得到您的回复。