私はコードでJava Callable 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();
}
}
以下は、Callableインターフェイスを実装するTask
クラスです。ホスト名に応じてURLを生成し、RestTemplate
を使用してSERVERSを呼び出す必要があります。最初のホスト名に例外がある場合は、別のホスト名のURLを生成して、電話をかけてみます。
class Task implements Callable<String> {
private static RestTemplate restTemplate = new RestTemplate();
@Override
public String call() throws Exception {
//.. some code
for(String hostname : hostnames) {
if(hostname == null) {
continue;
}
try {
String url = generateURL(hostname);
response = restTemplate.getForObject(url, String.class);
// make a response and then break
break;
} catch (Exception ex) {
ex.printStackTrace(); // use logger
}
}
}
}
だから私の質問はRestTemplate
を静的グローバル変数として宣言する必要がありますか?または、このシナリオでは静的であってはなりませんか?
static
またはインスタンスのどちらでも構いません。
HTTPリクエストを作成するためのRestTemplate
のメソッドはスレッドセーフであるため、RestTemplate
インスタンスごとにTask
インスタンスがあるか、すべてのTask
インスタンスの共有インスタンスがあるかは関係ありません(ガベージコレクションを除く)。
個人的には、RestTemplate
クラスの外にTask
を作成し、それを引数としてTask
コンストラクターに渡します。 (可能な場合は常に制御の反転を使用してください。)
私の特定のケースでは、RestTemplate
のインスタンスを複数持つ必要がある理由がいくつか見つかりました。
RestTemplateはリモートエンドポイントを呼び出す方法ですが、HTTP統合は一見シンプルに見えます。すべてのAPI呼び出しに適用されない特別なシナリオを見つけ始めたときは、ケースバイケースでいくつかの設定を定義する方法が必要であることに気付いたときです。基礎。
このようなシナリオの例は次のとおりです。
すでに述べたように、RestTemplateはスレッドセーフです。
ただし、単体テストの場合、静的変数を使用すると、彼の呼び出しをモックするためのいくつかの問題が発生します。したがって、クラスコンストラクターを使用してRestTemplateを挿入することを検討してください。
@Service
class LoginService {
private final RestTemplate restTemplate;
public LoginService(final RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
}