【发布时间】:2020-05-11 20:22:33
【问题描述】:
我的代码中有以下类,你可以说它只是标准RestTemplate 的包装。因此,每当我们必须发出外部请求而不是使用RestTemplate 时,我们autowire 自定义MyRestTemplate。
@Service
@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyRestTemplateImpl implements MyRestTemplate {
private final RestTemplate restTemplate;
private Logger logger = LogManager.getLogger(MyRestTemplateImpl.class);
@Autowired
public MyRestTemplateImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException {
ResponseEntity responseEntity = restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
return responseEntity;
}
}
现在的问题是我正在进行一些 Async 的休息调用,而后者又会调用 MyRestTemplate 来发出外部 REST 请求。
但它未能给出以下错误:
创建名为“scopedTarget.myRestTemplateImpl”的 bean 时出错: 范围“请求”对当前线程无效;考虑 如果您打算引用它,请为此 bean 定义一个作用域代理 单身人士
我知道这是因为为Async 操作生成了一个新线程,而request 的作用域对该子线程无效。它可以通过使用来自How to enable request scope in async task executor 的非常好的解决方案来解决,但是,我现在不想这样做,因为这种异步操作并不常见,而且我有一些时间限制。
所以,我的主要问题是,如果我将 MyRestTemplateImpl 设为 singleton 一切正常,我没有遇到任何此类问题。
但是有很多方法使用MyRestTemplateImpl 处理外部请求,并且应用程序上的流量也大量。
将其从Request 更改为Singleton 是否会导致任何不利影响,例如速度慢、竞争条件或任何我目前不知道或没有遇到的有害影响?
如果是的话,如果你能给出正确的解释,除了范围之间的基本区别之外,它会很棒,因为当我现在开始编码时,它会给我更好的推理,同时确定 bean 的范围。 如果不是,为什么?
我知道每个请求都会创建一个新的 bean,但请用小例子解释 request 范围的实际用例是什么?
【问题讨论】:
-
只要不保持状态就没什么好担心的。构造后的
RestTEmplate是线程安全的。它甚至可以提高性能和内存使用率。
标签: spring spring-boot asynchronous scope