java 如何有效地将 HttpComponentsClientHttpRequestFactory 与 RestTemplate 一起使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29466443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:19:56  来源:igfitidea点击:

How to use HttpComponentsClientHttpRequestFactory with RestTemplate efficiently?

javamultithreadingspringthread-safetyresttemplate

提问by AKIWEB

I am using RestTemplatealong with its factory HttpComponentsClientHttpRequestFactoryin one of my projects. In this project, I need to make a Http url call to my server which is running a restful service which returns back the response as a JSON String.

我在我的一个项目中使用RestTemplate及其工厂HttpComponentsClientHttpRequestFactory。在这个项目中,我需要对我的服务器进行 Http url 调用,该服务器正在运行一个 Restful 服务,该服务将响应作为 JSON 字符串返回。

Below is my code -

下面是我的代码 -

public class GetUserClientData {

    public String getData(KeyHolder keys) {
        return new HTTPRequestAccess(keys).makeHttpRequest();
    }
}

Below is my class which wraps the HttpClient part -

下面是我的类,它包装了 HttpClient 部分 -

public class HTTPRequestAccess {

    // should this be static?
    private RestTemplate restTemplate;
    private KeyHolder keys;
    private int timeout;

    public HTTPRequestAccess(KeyHolder keys){
        this(keys.getTimeoutValue()); // setting timeout to RestTemplate
        this.keys = keys;
    }

    public HTTPRequestAccess(int timeout) {
        this.timeout = timeout;
        restTemplate = new RestTemplate(clientHttpRequestFactory());
    }

    private ClientHttpRequestFactory clientHttpRequestFactory() {
        // is this not expensive that every time we are creating this new object?
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(timeout);
        factory.setConnectTimeout(timeout);
        return factory;
    }

    public String makeHttpRequest() {
        String response = null;        
        try {
            // some logic here

            String url = generateURL();
            response = restTemplate.getForObject(url, String.class);

            // some logic here
        } catch (RestClientException ex) {
            // log exception and do some stuff
        } catch (Exception ex) {
            // log exception
        }

        return response;
    }
}

Should RestTemplateand HttpComponentsClientHttpRequestFactorybe static here in my HTTPRequestAccessclass as if I see it correctly, I am recreating the whole connection pool for each request in RestTemplatewhich is not the right way I guess because each factory has connection and thread pool and they are pretty heavy object I guess.

在我的课堂上应该RestTemplate并且HttpComponentsClientHttpRequestFactory是静态的,HTTPRequestAccess就好像我正确地看到它一样,我正在为每个请求重新创建整个连接池,RestTemplate我猜这不是正确的方式,因为每个工厂都有连接和线程池,我猜它们是非常重的对象.

In general what is the best way to use RestTemplatealong with its factory HttpComponentsClientHttpRequestFactoryin a multithreading environment? I guess RestTemplateis thread safe but I don't think HttpComponentsClientHttpRequestFactoryis thread safe. Correct me if I am wrong? I will be running this library under heavy load.

一般来说,在多线程环境中RestTemplate与其工厂一起使用的最佳方法是什么HttpComponentsClientHttpRequestFactory?我猜RestTemplate是线程安全的,但我认为HttpComponentsClientHttpRequestFactory不是线程安全的。如果我错了,请纠正我?我将在重负载下运行这个库。

I am using spring-web-3.2.8.RELEASEversion.

我正在使用spring-web-3.2.8.RELEASE版本。

回答by Youness

In one of my projects, I had created a static instance of HttpComponentsClientHttpRequestFactory and passed it to every RestTemplate. Though, in here, it is suggested to also have a global instance of RestTemplate.

在我的一个项目中,我创建了 HttpComponentsClientHttpRequestFactory 的静态实例并将其传递给每个 RestTemplate。不过,在这里,建议也有一个 RestTemplate 的全局实例。

Maybe irrelevant, but one important point is to pass HttpClients.createDefault() to your HttpComponentsClientHttpRequestFactory while constructing it since by default, this factory uses system properties to create HttpClient for your factory and that may cause a lot of pain in production environment. You may also pass your custom HttpClient.

也许无关紧要,但重要的一点是在构造它时将 HttpClients.createDefault() 传递给您的 HttpComponentsClientHttpRequestFactory 因为默认情况下,此工厂使用系统属性为您的工厂创建 HttpClient ,这可能会在生产环境中造成很多痛苦。您还可以传递您的自定义 HttpClient。