SpringBootでJerseyを使用する

Sep 15 2020

7.3JAX -RSおよびJerseyというタイトルのセクションのSpringBootリファレンスドキュメントには、「登録されているすべてのエンドポイントは、HTTPリソースアノテーション(@GETなど)を含む@Componentsである必要があります。エンドポイントはSpring @Componentであるため、そのライフサイクルはSpringによって管理されます。また、@ Autowiredアノテーションを使用して依存関係を挿入し、@ Valueアノテーションを使用して外部構成を挿入することができます。

ただし、Jerseyリソースに依存関係を挿入したり、外部構成を挿入したりする必要はないため、Jerseyリソースに@Componentsとしてアノテーションを付けませんでした。私のアプリは問題なく動作します。

Spring Bootリファレンスドキュメントを読んだところ、Jerseyリソースを@Componentsとして登録することが要件であるように思われました。しかし、そうではないようです。私には、これはSpringBootリファレンスドキュメントの小さなバグのように思えます。ドキュメントを「登録済みエンドポイントは@Componentsにする必要があります」から「登録済みエンドポイントは@Componentsにすることができます」に更新できる可能性があります。これは意味がありますか?

回答

RahulKhimasia Sep 17 2020 at 04:29

これを試してみたところ、JerseyリソースにSpring @ Componentアノテーションを付けることはオプションであることがわかりました。そのアノテーションを使用する場合、リソースのライフサイクルはSpringによって管理され、そのアノテーションを使用しない場合、ライフサイクルはJerseyによって管理されます。

注意すべき重要な点の1つは、そのライフサイクルがデフォルトでプログラムされる方法に2つの間で大きな違いがあるということです。

ジャージーユーザーガイドのセクション3.4に記載されているように、「デフォルトでは、ルートリソースクラスのライフサイクルはリクエストごとです。つまり、リクエストURIパスがルートリソースと一致するたびに、ルートリソースクラスの新しいインスタンスが作成されます。これにより、同じリソースへの複数の同時リクエストを気にせずにコンストラクターとフィールドを利用できる非常に自然なプログラミングモデルが実現します。一般に、これがパフォーマンスの問題の原因になる可能性はほとんどありません。JVMのクラス構築とガベージコレクションが大幅に改善されました。 HTTPリクエストを処理して処理し、HTTPレスポンスを返すために、何年にもわたって多くのオブジェクトが作成および破棄されます。」

しかし、SpringFrameworkのドキュメント セクション1.5で述べられているように; デフォルトでは、Beanはシングルトンです。「SpringIoCコンテナーは、そのBean定義によって定義されたオブジェクトのインスタンスを1つだけ作成します。この単一インスタンスは、そのようなシングルトンBeanのキャッシュに格納され、その名前付きBeanに対する後続のすべての要求と参照は、キャッシュされたオブジェクトを返します。」

したがって、違いがあります。通常のJerseyルートリソースクラスはデフォルトでリクエストごとにインスタンス化されますが、Springではリソースに@Componentアノテーションが付けられるとシングルトンになります。つまり、JVMの存続期間中は1つのインスタンスのみです。Springマネージリソースに通常のJerseyリソースと同じリクエストごとのライフサイクルを持たせたい場合は@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)、@ Componentアノテーションに加えてSpringアノテーションを追加する必要があります。これを追加することで、リソースのライフサイクルがリクエストごとになります。