報錯
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
解決方案
- 取消熔斷
feign.hystrix.enabled=false
- 切換隔離等級
hystrix.command.default.execution.isolation.strategy=SEMAPHORE
- 線程間傳遞上下文
a.hystrix.shareSecurityContext=true
b. 注入自定義RequestInterceptor
, 在請求中設定HTTP header
@Bean
public RequestInterceptor oAuth2RequestInterceptor() {
return template -> {
// 在org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter
// 過濾器中,已經將OAuth2Authentication放大了請求上下文中,所以沒有使用instanceof判斷
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder
.getContext().getAuthentication();
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) oAuth2Authentication.getDetails();
template.header("Authorization", details.getTokenType() + " " + details.getTokenValue());
};
}
- 在代碼內有線程切換的情況下(比如使用paralleStream),需要在線程內設置上下文
SecurityContext context = SecurityContextHolder.getContext();
List<Integer> list = xxxxService.findByxxxx(xxxx);
list.parallelStream().forEach(
SecurityContextHolder.setContext(context);
l -> xxxxClient.findByXxxx(l); // 請求其他服務的接口
);
原因
獲取callable接口的實現類,可以看到獲取了父線程的上下文
在新線程中先設定請求上下文