Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java RestTemplate应该是静态全局声明的吗?_Java_Multithreading_Resttemplate_Callable - Fatal编程技术网

Java RestTemplate应该是静态全局声明的吗?

Java RestTemplate应该是静态全局声明的吗?,java,multithreading,resttemplate,callable,Java,Multithreading,Resttemplate,Callable,我在代码中使用Java可调用的Future。下面是我使用future和callables的主要代码- public class TimeoutThread { public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); Future<String> future =

我在代码中使用Java可调用的Future。下面是我使用future和callables的主要代码-

public class TimeoutThread {

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newFixedThreadPool(5);
        Future<String> future = executor.submit(new Task());

        try {
            System.out.println("Started..");
            System.out.println(future.get(3, TimeUnit.SECONDS));
            System.out.println("Finished!");
        } catch (TimeoutException e) {
            System.out.println("Terminated!");
        }

        executor.shutdownNow();
    }
}

所以我的问题是,我应该将
restemplate
声明为静态全局变量吗?或者在这种情况下它不应该是静态的?

无论是静态的还是实例的都不重要

restemplate
发出HTTP请求的方法是线程安全的,因此每个
Task
实例都有一个
restemplate
实例,还是所有
Task
实例都有一个共享实例都是无关的(垃圾收集除外)


就我个人而言,我会在
任务
类之外创建
RestTemplate
,并将其作为参数传递给
任务
构造函数。(尽可能使用控制反转。)

从并发性的角度来看,这无关紧要<代码>RestTemplate是线程安全的,因此单个实例或多个实例与程序的正常运行无关

但您可能需要考虑“代码> AxyRistStase< /Cord>”,如图所示。


另外,正如其他人提到的,您应该考虑IOC方法来将REST客户端的创建与它的使用分开。Martin Fowler的文章是关于该主题的开创性讨论。

在我的特殊案例中,我找到了一些原因,说明人们可能希望有多个
RestTemplate
实例

RestTemplate是一种调用远程端点的方法,但是HTTP集成看起来非常简单,当您开始发现不适用于所有API调用的特殊场景时,您就会意识到需要一种方法来逐个定义一些设置

此类场景的示例如下:

  • 我们公司有不同的团队,我们错误地没有就我们想要在模型中使用的时间格式达成一致。现在,来自不同团队的不同API使用不同的时间格式,这迫使我们为这些情况定义不同的JSON映射器设置。如果必须调用第三方服务,也可能发生这种情况
  • 并不是所有我们调用的API都有相同的服务级别协议,或者全年都有相同的行为。在旺季,某些API可能需要支持更多流量等。这意味着不同API的连接超时设置可能不同,有时甚至取决于需求。因此,连接超时、读取超时和写入超时等设置可能会根据您调用的服务进行不同的配置
  • 可能断路器设置(如Hytrix的断路器设置)需要针对每个服务进行配置,因此针对每个服务配置一个RestTemplate实例可以让您更方便地根据具体情况配置设置

如前所述,RestTemplate是线程安全的

但是,对于单元测试,使用静态变量会给您带来一些问题来模拟他的调用。因此,考虑使用类构造函数注入REST模板:

@Service
class LoginService {

    private final RestTemplate restTemplate;

    public LoginService(final RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
}

“就个人而言,我会创建…”或使用依赖注入;)+1@Rc对,这就是我的意思,尽可能的控制反转。如果可能的话,也可以使用DI容器。@SotiriosDelimanolis:谢谢你的建议。。您能否提供一个示例,说明如何在类外部创建RestTemplate,然后将其作为参数传递给任务构造函数?@Akiweb创建一个接受
RestTemplate
参数的
Task
构造函数。然后执行
newtask(restemplate)
其中
restemplate
是调用方管理的
restemplate
参考。谢谢。。但这样做的好处是什么?只是想了解我的做法和你的建议有什么不同?@Vidya我也有类似的问题,与上次你帮助我的
RestTemplate
有关。如果可能的话,你也能帮我吗?非常感谢您的帮助。我没有看到在RestTemplate或实现请求执行逻辑的类中使用synchronized。如何保证线程安全?拥有多个RestTemplate的另一个用例是,我有一个应用程序,可以与多个HTTP服务器交互,每个服务器都具有不同的凭据和身份验证类型。对于每台服务器,我都有一个不同的RestTemplate。关于第2点,即使在RestTemplate初始化之后,您也不能更改requestFactory的超时吗?因此ServiceA.methodA()可以在执行请求之前动态设置读取超时,ServiceB.methodA()也是如此。如果我错了,请纠正我,因为我正试图在我的项目中实现一个好的设计。谢谢,我们也有类似的情况。在我们的应用程序中,我们需要连接到3个或更多不同的HTTP/HTTPS服务器,并且我们必须为每个服务器定义超时和定制的HTTPClient。因此,对于一些客户机,我们必须使用来自
httpcomponents客户端httprequestfactory
的restTemplate,它具有使用自己的可配置客户机的功能,对于少数SimpleClientHttpRequestFactory客户机的功能。因此,我们最终得到了单独的RestTemplate(尽管可以使用相同类型的minimuim)。尽管如此,如果有人有任何好办法,除了这个,请分享。
@Service
class LoginService {

    private final RestTemplate restTemplate;

    public LoginService(final RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
}