1

Java EE と JBoss Application Server を使用してペイント サービスを実装したいと考えています。

URL経由で呼び出されるメソッドを想像してください

http://mypaint.com/apply?image=1&action=line&from=10,10&to=100,10

id 1 の画像にアクションを適用します。アクションは「点 (10,10) から点 (100,10) まで線を引く」です。

「適用」メソッドは次のようになります。

@Inject
private ImageProcessorServer processors

@GET
@Path("/apply")
public Response apply(
    @QueryParam(value = "image") int imageId,
    @QueryParam(value = "action") String action,
    //some parameters more...
) {
     … //check if user is allowed to access the image
     ImageProcessor processor = processors.get(imageId); 
       //get image processor by image id
     processor.apply(action/*, from, to*/);
}

「ImageProcessorServer」は次のようになります。

@Singleton
@Startup
public class ImageProcessorServer {
   private Map<Integer, ImageProcessor> processors =
       new HashMap<Integer, ImageProcessor>();  
   @Lock(LockType.WRITE)
   public ImageProcessor get(int imageId) {
       ImageProcessor processor = processors.get(imageId);
       if(processor == null) {
           processor = new ImageProcessor(imageId);
           processors.put(imageId, processor);
       }
       return processor;
   }
}

Image ごとに 1 つの ImageProcessor のみが生成されるようにするためのシングルトンです (相互排除下での生成 → Write-Lock)。

問題: ImageProcessor クラスにデータ アクセス オブジェクト (データベースを操作するため) を挿入するにはどうすればよいですか? DAO は単純なステートレス Bean です。私の ImageProcessor は次のようになります。

public class ImageProcessor {
   @Inject
   private ActionDao actionDao;
   private Image image;

   public ImageProcessor(int imageId) { … }

   public void apply(String action, ...) {
      //change image
      //actionDao.persist(actionObject)
   }
}

しかし、これはうまくいきません。ActionDao は NULL です。

私の現在の解決策は、次のように、DAO を使用しているすべてのメソッドでパラメーターとして DAO を渡すことです。

public ImageProcessor(int imageId, ImageDao dao) { … }

public void apply(String action, …, ActionDao dao, ImageDao dao2, …) {
   //change image
   //dao.persist(actionObject)
}

同じイメージ ID を持つリクエストは、同じイメージ プロセッサを共有することが重要です。クライアントは、異なるイメージ ID を持つ複数のリクエストを持つことができます。

このリンク下 POJO で依存性注入を使用して EJB を注入 すると、ファクトリを使用できると言われています。しかし、私はこれを解決する方法がわかりません。誰かがこれのコードを提供できますか?

誰かが私の問題を解決するエレガントな方法を知っていますか?

4

3 に答える 3

1

あなたの場合、Bean を手動で検索できます。そのためには、静的 util メソッドを追加して Bean マネージャーを取得できます。

 public static BeanManager getBeanManager()
 {
    try{
        InitialContext initialContext = new InitialContext();
        return (BeanManager) initialContext.lookup("java:comp/BeanManager");
    catch (NamingException e) {
        log.error("Couldn't get BeanManager through JNDI");
        return null;
    }
  }

その後、シングルトン EJB で Bean を手動でルックアップできます。その後、すべてのインジェクションが Bean で発生します。

 public ImageProcessor getFacade()
 {
    BeanManager bm = getBeanManager();
    Bean<ImageProcessor> bean = (Bean<ImageProcessor>) bm.getBeans(ImageProcessor.class).iterator().next();
    CreationalContext<ImageProcessor> ctx = bm.createCreationalContext(bean);
    ImageProcessor ip= (ImageProcessor) bm.getReference(bean, ImageProcessor.class, ctx); // this could be inlined, but intentionally left this way
    return ip;
 }

Bean を検索した後、setter メソッドを使用してイメージ ID を設定し、それをマップに配置します。

Bean を手動で探すための util クラスを作成してみてください。その後、プロジェクト全体で再利用できます。

また、Seam3、Myface CODI、および DeltaSpike には、これらのルーチン プロセスを実行するためのユーティリティがいくつかあります。

詳細については、このサンプルをご覧ください。

于 2012-08-30T03:06:50.927 に答える
0

フィールドを注入するには、CDI フレームワークによって Bean を作成する必要があります。

「CDI」を作成するいくつかの方法を見つけることができますImageProcessorが、imageId のスコープとプロセッサの間に主権があるため、見栄えがよくありません。(FYI 初期化が必要な Bean は、@Producerアノテーション付きメソッドを介して作成する必要があります)

この問題を解決する最も簡単な方法は、シングルトンに DAO を挿入し (ステートレスであるため問題にならないはずです)、コンストラクターを介してプロセッサに提供することです (DAO フィールドを設定します)。これはクレンジングの方法だと思います。ImageProcessor作成をシングルトンに限定します)

于 2012-08-29T18:46:53.027 に答える
0

EJB はシングルトンであり、すべての注入は EJB の作成時に 1 回行われるため、プロデューサ メソッドを使用する方法が見つかりませんでした。

まず修飾子アノテーションを追加します: @ImageProcessor

次に、プロデューサー メソッドを定義します。

@produces  @ImageProcessor
public ImageProcessor getImageProcessor(){
  long imageId = // Get your image id from request parameter map
  ImageProcessor processor = new ImageProcessor(imageId);
  return processor;
} 

次に、シングルトンで注入を使用する場合、EJB がシングルトンであるため、すべてのイメージに対して 1 回注入されます。

@Inject @ImageProcessor
private ImageProcessor ip;     

したがって、ユースケースでは、EJB で手動ルックアップを再度使用しない限り、これは良いアプローチではありませんが、別の問題はプロデューサーメソッドのスレッド化の問題です!

于 2012-08-30T03:20:29.473 に答える