如何通过 RequestFactory 高效使用 RestTemplate?

How to use RestTemplate efficiently with RequestFactory?

我正在做一个项目,我需要对我的服务器进行 HTTP URL 调用,该服务器是 运行 Restful 服务,returns 返回响应作为 JSON 字符串。我在这里使用 RestTemplateHttpComponentsClientHttpRequestFactory 来执行 url.

我在 RestTemplate 上使用 HttpComponentsClientHttpRequestFactory.

设置了一个 http 请求超时(READ 和 CONNECTION 超时)

下面是我的界面:

public interface Client {

    // for synchronous
    public String getSyncData(String key, long timeout);

    // for asynchronous
    public String getAsyncData(String key, long timeout);
}

下面是我对客户端接口的实现-

public class DataClient implements Client {

    private final RestTemplate restTemplate = new RestTemplate();
    private ExecutorService executor = Executors.newFixedThreadPool(10);

    // for synchronous call
    @Override
    public String getSyncData(String key, long timeout) {
        String response = null;

        try {
            Task task = new Task(key, restTemplate, timeout);

            // direct call, implementing sync call as async + waiting is bad idea. 
            // It is meaningless and consumes one thread from the thread pool per a call.               
            response = task.call();
        } catch (Exception ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
        }

        return response;
    }

    // for asynchronous call
    @Override
    public Future<String> getAsyncData(String key, long timeout) {
        Future<String> future = null;

        try {
            Task task = new Task(key, restTemplate, timeout);
            future = executor.submit(task); 
        } catch (Exception ex) {
            PotoLogging.logErrors(ex, DataErrorEnum.CLIENT_ERROR, key);
        }

        return future;
    }
}

下面是我的简单任务class

class Task implements Callable<String> {

    private RestTemplate restTemplate;
    private String key;
    private long timeout; // in milliseconds

    public Task(String key, RestTemplate restTemplate, long timeout) {
        this.key = key;
        this.restTemplate = restTemplate;
        this.timeout = timeout;
    }

    public String call() throws Exception {

        String url = "some_url_created_by_using_key";

        // does this looks right the way I am setting request factory?
        // or is there any other effficient way to do this?
        restTemplate.setRequestFactory(clientHttpRequestFactory());
        String response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);

        return response;
    }

    private static ClientHttpRequestFactory clientHttpRequestFactory() {
        // is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(timeout); // setting timeout as read timeout
        factory.setConnectTimeout(timeout); // setting timeout as connect timeout
        return factory;
    }   
}

现在我的问题是 - 我每次在任务 class 的调用方法中使用 RestTemplatesetRequestFactory 的方式是否有效?由于 RestTemplate 的创建非常繁重,所以不确定我是否做对了。

并且每次都创建一个 HttpComponentsClientHttpRequestFactory 的新实例可以吗?会贵吗?

如果我们需要在其上设置读取和连接超时,那么使用 RestTemplate 的正确有效方法是什么。

这个库会这样使用 -

String response = DataClientFactory.getInstance().getSyncData(keyData, 100);

据我所知,您重复使用同一个 RestTemplate 对象,但每个 Task 都在执行这一行:restTemplate.setRequestFactory(clientHttpRequestFactory());。这似乎可以有竞争条件,例如一个 Task 可以设置另一个 Task 会意外使用的 RequestFactory

否则,您似乎在正确使用 RestTemplate

您的超时设置多久更改一次?如果您主要使用一个或两个超时,则可以使用具有预加载超时的 RequestFactory 构造函数创建一个或两个 RestTemplate。如果您是效率的坚持者,请创建一个 HashMap<Integer, RestTemplate>,每次请求新的超时时缓存 RestTemplate 和特定的超时。

否则,查看 RestTemplate's constructor, and for HttpComponentsClientHttpRequestFactory's constructor 的代码,它们看起来并不特别重,因此重复调用它们可能不会成为太大的瓶颈。