如何有效地使用HttpComponentsClientHttpRequestFactory和RestTemplate?

时间:2015-04-06 06:29:23

标签: java multithreading spring thread-safety resttemplate

我在其中一个项目中使用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;
    }
}

我的RestTemplate类中HttpComponentsClientHttpRequestFactoryHTTPRequestAccess应该是静态的,就像我正确看到它一样,我正在为RestTemplate中的每个请求重新创建整个连接池。我想是不正确的方法,因为每个工厂都有连接和线程池,我猜它们是非常重的对象。

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

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

1 个答案:

答案 0 :(得分:2)

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

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