EJB и хранение объектов в структуре данных (карта, список и т. д.)

StackOverflow https://stackoverflow.com/questions/636450

Вопрос

Возможно ли хранить объекты в структуре данных на протяжении всего времени работы сервера приложений?По сути, мне нужен 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();

}

Вот сессионный компонент:

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 будет заменен из пула компонентов). Можно ли каким-то образом внедрить это как ресурс?

Это было полезно?

Решение

Это можно сделать, поместив карту в синглтон и получив доступ к этому синглтону из бобов. Таким образом, существует один экземпляр для всех экземпляров EJB (поскольку они совместно используют один и тот же загрузчик классов). Разные Session-бины в разных EAR не будут работать, так как у каждого из них будет свой собственный загрузчик классов, но это не похоже на ваш сценарий.

Используемое вами ConcurrentHashMap в достаточной степени справится с большинством ваших случаев, но вам все равно нужна синхронизация вокруг метода addAnimal, поскольку вам нужно, чтобы карта была согласованной между двумя вызовами метода.

Другие советы

Новая спецификация EJB 3.1 предоставляет новый тип bean-компонентов - Singleton-бины - именно то, что вам нужно. Единственная реализация с частичной поддержкой EJB 3.1, о которой я знаю, - это Apache OpenEJB 3.1. Он включает в себя бобы Singleton, но я их еще не использовал.

Это сессионный компонент без сохранения состояния. Как следует из названия, вы не должны иметь никакого состояния в таком бобе. Контейнер EJB может работать с несколькими экземплярами вашего компонента для удовлетворения одновременных запросов. Как вы синхронизируете данные списков всех экземпляров? Я думаю, что нет никакого способа сделать это.

Включение такого List в сессионный компонент, обеспечивающий бизнес-логику, на мой взгляд, даже нарушает концепцию бизнес-уровня. Вы должны позаботиться о транзакциях и одновременной записи самостоятельно.

Почему вы не держите Список животных на стороне клиента? Я думаю, что так будет лучше.

Я думаю, что лучше всего было бы полностью вынести структуру данных из EJB и сохранить ее как статическую структуру данных.Вероятно, вы правы в том, что ваши объекты удаляются из-за объединения EJB в пул.

Обратите внимание, что в зависимости от того, как вы реализуете доступ к структуре данных, вам может потребоваться синхронизировать доступ, чтобы обеспечить безопасность потоков.

Если вы хотите поддерживать состояние внутри вашего EJB, рассмотрите возможность использования сессионных компонентов с сохранением состояния.Кроме того, если вы хотите увидеть, когда bean-компоненты уничтожались, вы можете переопределить метод ejbremove, я забыл аннотацию для Java 5.

Карл

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top