1

単純さと正確さの観点から、同じクラスのオブジェクトを異なるスコープで注入するための最良の方法は何ですか?

サーブレットで、スコープが異なる同じクラスのオブジェクトを挿入したいと思います。jsfを使用するかどうかはまだわかりません。

  • シンプルさ:Qualifierスコープごとにとプロデューサーメソッドを作成するのは多すぎます。インターフェイスの作成、2つのクラス、および追加と代替beans.xmlも多すぎます。メソッドを持つことAddress#isCurrent()は意味がありません。
  • 正しさ:JSR299、3.11によると:注入ポイント修飾子として@Namedを使用することはお勧めしません。 まだ理由はわかりません。インジェクションポイントで
    使用すると 、では機能しますが、では機能しません。以下の名前付きスニペットを参照してください。@Named@ApplicationScoped@RequestScoped@SessionScoped

春にはとても簡単です:
春のスニペット

<bean id="currentAddress" class="xxx.Address" scope="session" />
<bean id="newAddress" class="xxx.Address" scope="request" />
<bean id="servlet" class="xxx.MyServlet">
 <property name="currentAddress" ref="currentAddress" />
 <property name="newAddress" ref="newAddress" />
</bean>


名前付きスニペット

/* Address class */
@Produces @RequestScoped @Named(value="request")
 public Address getNewAddress(){
 return new Address();
}

@Produces @SessionScoped @Named(value="application")
 public Address getCurrentAddress(){
 return new Address();
}
/* Servlet */
@Inject @RequestScoped @Named("request")  private Address newAddress;
@Inject @ApplicationScoped @Named("application") private Address currentAddress;
4

2 に答える 2

4

この推奨事項が含まれている理由は、定数の任意の文字列よりも列挙を好む理由と同じです。これは、タイプセーフではないためです。クラスの名前を簡単にタイプミスすると、正常にコンパイルされ、実行時に失敗します。@namedは、コンパイル時にこれらの制約を強制する機能がある場合、ほとんどの場合、アプリケーションを不必要に脆弱にするため、推奨事項が含まれています。

理由を概説した良い記事があります:

この状況を処理するための推奨される方法は、列挙値を持つ@Qualifiersを使用することです。これを処理する手順については、「文字列修飾子はレガシーです」および「正しい方法」というタイトルのセクションを確認してください。

于 2012-04-29T17:37:24.823 に答える
2

その良い記事を指摘してくれた@nsfyn55のおかげで、「正しい方法」のセクションを読んだ後、私は単純さと正確さの観点からそれを達成するための最良の方法だと思うものを思いつきました。

したがって、修飾子アノテーションに使用しているインターフェースは1つだけです。

/* Qualifier annotation */
@Qualifier
@Retention(RUNTIME)
@Target({FIELD,METHOD})
public @interface Scope {

 Type value();

 enum Type { REQUEST, SESSION, APPLICATION };
}


/* Address class */
@Produces @Scope(REQUEST) @RequestScoped
 public Address request() {
 return new Address();
}

@Produces @Scope(SESSION) @SessionScoped
 public Address session() {
 return new Address();
}

/* Servlet */
@Inject @Scope(REQUEST)
private Address newAddress;

@Inject @Scope(SESSION)
private Address currentAddress;
于 2012-05-04T18:14:49.233 に答える