web-dev-qa-db-ja.com

Spring @Repositoryのベストプラクティス

コンテキスト:Webアプリケーション

Springを使用したことはありませんが、Springのドキュメントによると、singletonとして宣言しない限り、すべてのBeanはprototypeです。

  • Springを使用しない場合:

通常、ビジネス/サービス層への呼び出しがある場合、新しいDAOをインスタンス化します。 RESTfullサービスの場合、呼び出しに依存するほとんどすべてのオブジェクトをインスタンス化します。

  • 春の場合:

_@Repository_を使用してデータアクセスクラスに注釈を付けたり、サービスレイヤークラスに_@Service_を使用したりできます。

そのため、上記のアノテーションを持つ私のクラスはデフォルトでsingletonです。プロトタイプとして宣言できる_@Scope_注釈がありますただし、これを行う人はいないようです

  • Springなし:new Object();毎回
  • Springの場合:singleton

私の質問は、

  1. 以前の使用方法(毎回新しいインスタンスを作成する)が間違っていますか?
  2. _@Repository_がsingletonである場合、そのようなことが解決されていない場合、スレッドセーフをどのように処理しますか? (春のプロキシによって行われると仮定します)
  3. ベストプラクティスは何ですか、_@Repository_で十分ですか、または@Scope('prototype')を追加する方が良いでしょうか?
  4. @Scope('prototype')を_@Repository_と共に使用する人はいません(チュートリアル、ブログなどによる)。よく知られた理由はありますか?
  5. 多数のスレッドが非常に高い頻度でDAOクラスにアクセスした場合はどうなりますか? (これは私が最も心配するものです)

ありがとう

30
sura2k

正解です。-Spring worldでは、ほとんどのBeanはシングルトンです。

  1. 以前の使用方法(毎回新しいインスタンスを作成する)が間違っていますか?

動作するので間違っていません。それに関する問題は、各リクエストでDAOの新しいインスタンスをインスタンス化することです-場合によっては高価であり、とにかく意味をなさないかもしれません-なぜDAOインスタンスの束が必要なのでしょうか?一方、Springはシングルトンを作成するだけでなく、DAOをサービスまたは他のDAOのe.t.cに注入します。すなわち、あなたのために多くの仕事をします

  1. @Repositoryがシングルトンの場合、対処されていない場合にスレッドセーフをどのように処理しますか? (春のプロキシによって行われると仮定します)

@Repository Beanを作成する場合、通常、そこにDataSourceまたはEntityManagerを挿入します。 DataSource.getConnection()メソッドはスレッドセーフである必要があります。 EntityManagerに関して、Springは、異なるスレッドに対して異なる動作をするプロキシを注入します。つまり、異なるスレッドは同じJPAセッションを共有しません。

  1. ベストプラクティスは何ですか、@ Repositoryで十分です。または@Scope( 'prototype')を追加することをお勧めします。

ベストプラクティス(または最も広く普及しているアプローチ)は、単に@Repositoryを使用することです

  1. @Scope( 'prototype')を@Repositoryで使用している人はいません(チュートリアル、ブログなどによる)。よく知られた理由はありますか?

その理由は、@ Repository Beanの複数のインスタンスを作成しても利益がないからです。

  1. 多数のスレッドが非常に高い頻度でDAOクラスにアクセスした場合はどうなりますか? (これは私が最も心配するものです)

繰り返しますが、ここではシングルトンの方が、リクエストごとに新しいオブジェクトを作成するよりも優れています。冗長な同期を避けて、スレッドが何らかのモニターでブロックされないようにします

23
bedrin
  1. いいえ、ただし、単体テストははるかに困難です。これが依存性注入のすべてです。サービスにDAOを注入することにより、テスト中に模擬DAOを注入することにより、サービスを簡単に単体テストできます。サービスが独自のDAOを作成する場合、これは不可能です。

  2. リポジトリは、起動時に初期化されるスレッドセーフエンティティマネージャ、セッションファクトリ、またはJDBCテンプレートを除き、通常は完全にステートレスです。したがって、同時に呼び出されても問題ありません。スレッドセーフです。

  3. リポジトリがプロトタイプになる理由はありません。プロトタイプDAOをシングルトンサービスに挿入すると、とにかく各プロトタイプが同時に呼び出されます。

  4. それをする理由はありません。

  5. 問題ありません。正しくコーディングされていれば、スレッドセーフである必要があります。

1
JB Nizet

@Repositoryアノテーションが付けられたコンポーネントはシングルトンである必要があります。これは、そのライフタイム全体にわたって複数の状態や異なる状態になることは決してないためです。はい、保持できる唯一の状態は接続オブジェクトです。これは、オブジェクトの作成中に一度だけ設定されます。また、データストアと通信するためのロジック/メソッドが含まれ、各メソッドは必要なデータオブジェクトを取得/返します。そのため、リポジトリの複数のインスタンスを持つ必要はありません。

1
Manmay

Springは並行性の問題を処理しません。それは意図していません。アプリケーションが適切に動作できるように、作成するインスタンスの数を制御できるようにするだけです。

シングルトンスコープ(明らかに)は、指定されたBeanのインスタンスを1つだけ作成し、それをすべての依存オブジェクトに渡します。

各依存オブジェクトのプロトタイプスコープは、他のオブジェクト間で共有されない独自のインスタンスを作成します。

DAOオブジェクトの場合、データベースと通信するために複数のインスタンスが必要になることはほとんどありません。したがって、シングルトンはほとんど常に使用されます。

0
SimY4