【问题标题】:How to use HttpComponentsClientHttpRequestFactory with RestTemplate efficiently?如何有效地使用 HttpComponentsClientHttpRequestFactory 和 RestTemplate?
【发布时间】:2015-06-10 13:34:27
【问题描述】:

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

下面是我的代码 -

public class GetUserClientData {

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

下面是我的类,它包装了 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;
    }
}

如果RestTemplateHttpComponentsClientHttpRequestFactory 在我的HTTPRequestAccess 类中是静态的,就好像我没看错一样,我正在为RestTemplate 中的每个请求重新创建整个连接池,这不是我猜的正确方式,因为每个工厂都有连接和线程池,我猜它们是相当重的对象。

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

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

【问题讨论】:

    标签: java multithreading spring thread-safety resttemplate


    【解决方案1】:

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

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

    【讨论】: