1

App Serverの稼働時間中、オブジェクトをデータ構造に保存することは可能ですか?基本的に、このデータ構造とインターフェイスするEJBが必要ですが、本格的なデータベースソリューションは必要ありません。

例として、このダミーの動物オブジェクトを作成しました。

package com.test.entities;

public class Animal implements java.io.Serializable {

    private static final long serialVersionUID = 3621626745694501710L;
    private Integer id;
    private String animalName;

    public Integer getId() {
        // TODO Auto-generated method stub
        return id;
    }   
    public void setId(Integer id){
        this.id=id;
    }
    public String getAnimalName(){
        return animalName;

    }
    public void setAnimalName(String animalName){
        this.animalName=animalName;
    }
}

これがEJBリモートインターフェースです。

package com.test.beans;

import java.util.Map;

import javax.ejb.Remote;

import com.test.entities.Animal;

@Remote
public interface MapBeanRemote {

    public void addAnimal(Animal a);

    public void removaAnimal(Integer id);

    public Animal getAnimalById(Integer id);

    Map<Integer, Animal> getAllAnimals();

}

これがSessionBeanです。

package com.test.beans;

import java.util.ConcurrentHashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.Stateless;

import com.test.entities.Animal;

@Stateless(mappedName="ejb/MapBean")
public class MapBean implements MapBeanRemote{

    Map<Integer, Animal> animalStore;

    @PostConstruct
    public void initialize(){
        animalStore = new ConcurrentHashMap<Integer,Animal>();
    }

    @Override
    public void addAnimal(Animal a) {
        if(a.getId()!=null){
            animalStore.put(a.getId(), a);
        }
    }

    @Override
    public Animal getAnimalById(Integer id) {
        return animalStore.get(id);
    }

    @Override
    public void removaAnimal(Integer id) {
        animalStore.remove(id);

    }

    @Override
    public Map<Integer, Animal> getAllAnimals() {
        return animalStore;
    }

}

したがって、基本的には、動物マップを操作したいクライアントがこのEJBを通過し、各クライアントがオブジェクトの同じ正確なマップにアクセスできるようにする必要があります。

この例は十分に機能しません。しばらくすると、すべての動物が消去されます(EJBがBeanプールから置き換えられると想定しています)これはどういうわけかリソースとして注入できますか?

4

4 に答える 4

3

これは、マップをシングルトンに配置し、Bean からこのシングルトンにアクセスすることで実現できます。そうすれば、すべての EJB インスタンスに対して単一のインスタンスが存在します (同じクラスローダを共有するため)。異なるEARの異なるセッションBeanは、それぞれ独自のクラスローダーを持つため機能しませんが、それはあなたのシナリオではないようです。

ConcurrentHashMap の既存の使用法でほとんどのケースを十分に処理できますが、2 つのメソッド呼び出し間でマップを一致させる必要があるため、addAnimal メソッドの周りで同期が必要です。

于 2009-03-11T21:54:00.037 に答える
2

新しい EJB 3.1 仕様では、まさに必要としている新しいタイプの Bean (Singleton Bean) が提供されます。私が知っている EJB 3.1 を部分的にサポートする実装は、Apache OpenEJB 3.1 だけです。Singleton Bean が含まれていますが、まだ使用していません。

于 2009-03-23T13:52:35.490 に答える
1

これはステートレスセッションBeanです。名前が示すように、そのようなBeanでいかなる種類の状態も保持するべきではありません。EJBコンテナは、Beanの複数のインスタンスと連携して、同時リクエストを満たす場合があります。すべてのインスタンスのリストのデータをどのように同期しますか?私はこれを行う方法がないと思います。

そのようなリストをビジネスロジックを提供するセッションBeanに維持することは、私の意見ではビジネス層の概念にさえ違反します。トランザクションと同時書き込みは自分で処理する必要があります。

クライアント側で動物のリストを持ってみませんか?私はこれがより良い方法だと思います。

于 2009-03-11T21:42:41.077 に答える
0

データ構造をEJBから完全に移動し、静的データ構造として格納するのが最善の方法だと思います。EJBがプールされているためにオブジェクトが消去されているという事実は、おそらく正しいでしょう。

データ構造へのアクセスを実装する方法によっては、スレッドセーフを確保するためにアクセスを同期する必要があることに注意してください。

EJB内で状態を維持したい場合は、ステートフルセッションBeanを検討することを検討してください。また、Beanがいつ破棄されているかを確認したい場合は、ejbremoveメソッドをオーバーライドできます。Java5のアノテーションを忘れています。

カール

于 2009-03-11T21:41:43.107 に答える