1

是否可以在应用服务器正常运行期间将对象存储在数据结构中?基本上我想要一个与此数据结构接口的 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();

}

这是会话 Bean:

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;
    }

}

所以基本上我希望任何想要操作 Animal Map 的客户端都通过这个 EJB 并让每个客户端访问相同的对象 Map。

这个例子不够好。过了一会儿,所有的动物都被删除了(我假设当 EJB 从 bean 池中被替换时)这会以某种方式作为资源注入吗?

4

4 回答 4

3

这可以通过将 Map 放入 Singleton 并从 bean 访问此单例来完成。这样,所有 EJB 实例都有一个实例(因为它们共享相同的类加载器)。不同 EAR 中的不同会话 bean 将不起作用,因为它们每个都有自己的类加载器,但这似乎不是您的方案。

您现有的 ConcurrentHashMap 用法将足以处理您的大多数情况,但您仍然需要围绕 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 的多个实例一起工作以满足并发请求。如何同步所有实例的 Lists 数据?我觉得没有办法做到这一点。

将这样的 List 维护到提供业务逻辑的会话 bean 中,在我看来甚至违反了业务层的概念。您必须自己处理事务和并发写入。

为什么不在客户端保存动物列表?我认为这将是更好的方法。

于 2009-03-11T21:42:41.077 回答
0

我认为最好的想法是将数据结构完全移出 EJB 并将其存储为静态数据结构。您可能是正确的,因为 EJB 正在池中,因此您的对象正在被擦除。

请注意,根据您如何实现对数据结构的访问,您需要同步访问以确保线程安全。

如果您想在 EJB 中维护状态,请考虑查看有状态会话 bean。此外,如果您确实想查看 bean 何时被销毁,您可以覆盖 ejbremove 方法,我忘记了 Java 5 的注释。

卡尔

于 2009-03-11T21:41:43.107 回答