3

これが私のDAO実装です。テーブル全体をロードし、一定期間メモリにキャッシュします

@ApplicationScoped
public class DataAccessFacade {

   @Inject
   private EntityManager em;

   @CacheOutput
   public Map<String, String> loadAllTranslation() {
      List<Translation> list = em.createQuery("select t from Translation t").getResultList();    
      Map<String, String> result = new HashMap<String, String>();
      // do more processing here, omitted for clarity     
      return result;
   }

   public String getTranslation(String key) {
      return loadAllTranslation().get(key);
   }

}

ここに私のジャージークライアントがあります

@Inject
DataAccessFacade dataAccessFacade;

@Path("/5")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String t5(@QueryParam("id") String key) {
  // load the data from dataAccessFacade
  String text = dataAccessFacade.getTranslation(key); 
  String text2 = dataAccessFacade.loadAllTranslation().get(key); 
}

クライアントで dataAccessFacade.loadAllTranslation() を呼び出すと、インターセプター ロジックが実行されていることがわかります

内部で loadAllTranslation() を呼び出す dataAccessFacade.getTranslation() を呼び出すと、インターセプターが実行されたことを確認できませんでした。

ここで何が問題なのですか?

それを解決する方法は?

4

3 に答える 3

2

これは、CDI 仕様の正しい動作です。「クライアント」クラスによって呼び出されるメソッドのみが「ビジネス メソッド」と見なされるため、インターセプトされます。

于 2011-09-16T09:55:00.263 に答える
1

DataAccessFacade で次のことを行うだけです。

@Inject
private Provider<DataAccessFacade> self;

public String getTranslation(String key) {
  return self.get().loadAllTranslation().get(key);
}
于 2014-06-19T06:49:54.890 に答える
-1

クラスにバインドされたインターセプターは、すべてのメソッドをインターセプトします。インターセプター (@CacheOutput?) をクラス レベルではなく特定のメソッドにバインドすることを選択したようです。

loadAllTranslation に加えて getTranslation メソッドにインターセプターを明示的にバインドすると、両方の状況でインターセプターが機能することがわかると思います。

現在の動作を説明するための説明が仕様に見つかりませんでした。私の推測では、これは一種のカプセル化 (情報隠蔽) と考えることができます。外部的には、getTranslation の呼び出しが loadAllTranslation の呼び出しになると期待する理由はありません。getTranslation の呼び出しの結果として (明示的な注釈なしで) インターセプターが呼び出された場合、クラスの内部動作の詳細が漏洩しているように見える可能性があります。

于 2010-10-05T22:09:54.990 に答える