1. ホーム
  2. java

RestTemplateはスレッドセーフですか?

2023-09-19 19:45:28

質問

スプリングは RestTemplate はスレッドセーフですか?それは

  • RestTemplate で、複数の接続が安全に共有できるストラテジーオブジェクトです。 または
  • RestTemplate 接続オブジェクト (データベース接続のようなもの) で、使用中は共有できず、 接続ごとに新たに作成するか、プーリングする必要があります。

どのように解決するのですか?

RestTemplate はスレッドセーフです。 (強調)。

概念的には、非常によく似た JdbcTemplate , JmsTemplate といった、Spring Frameworkや他のポートフォリオプロジェクトで見られる様々なテンプレートがあります。これは、例えば RestTemplate は一度構築されるとスレッドセーフになります


のオブジェクトは RestTemplate クラスのオブジェクトは、HTTP を処理するためにその状態情報を一切変更しません。このクラスは、接続オブジェクトのようなものではなく、Strategy デザインパターンのインスタンスなのです。状態情報がないため、異なるスレッドが RestTemplate オブジェクトを共有しても、異なるスレッドが状態情報を破損したり、競争したりする可能性はありません。これが、スレッドがこれらのオブジェクトを共有することが可能である理由です。

を調べると のソースコードを調べると RestTemplate を使っていないことがわかるでしょう。 synchronized メソッドや volatile フィールドを使用して、オブジェクトの構築後にスレッドセーフを提供します。つまり、それは ではなく を修正するのは安全ではありません。 RestTemplate オブジェクトを修正するのは安全ではありません。特に、メッセージコンバータを追加することは安全ではありません。

メッセージコンバータのリストを提供するためには、以下のいずれかを行う必要があります。

  • を使用する。 RestTemplate(List<HttpMessageConverter<?>> messageConverters) のコンストラクタを使用します。の内部リストとして messageConvertersfinal は、この はメッセージコンバータのリストを安全に公開します。 .
  • を使用します。 setMessageConverters(List<HttpMessageConverter<?>> messageConverters) ミューテーター では 安全に公開する 変更された RestTemplate オブジェクトを作成します。Spring Beanの定義で <property name="messageConverters"><list>... がこれを行うので、ビーン はコンテナをセットアップするスレッドによって安全に発行されるからです。 を安全に発行するからです。
  • 使用方法 List.add によって返される参照に getMessageConverters() で返された参照にアクセスし、変更された RestTemplate オブジェクトを安全に公開します。しかし RestTemplate のドキュメントには、メッセージコンバータのリストを変更するために使用できる参照を返すとは明示的に記載されていません。現在の実装ではそうなっていますが、もしかしたら実装を変更して Collections.unmodifiableList またはリストのコピーを返すように実装が変更されるかもしれない。だから、このように変更しない方がいいかもしれない。

最初のケースは、オブジェクトを構築するときにメッセージコンバータを設定する唯一の手段であることに注意してください、したがってそれは です。 一旦構築されるとスレッドセーフであると言うのは正しいことです。

このクラスはSpring Frameworkの一部なので、ほとんどすべての実用的なケースでは、このクラスのオブジェクトはSpring Application Contextの一部として、最初の(コンストラクタによる依存性注入)または2番目の(セッタによる依存性注入)メソッドを使用してセットアップされます。