Поделитесь статическими синглетонами через EJB - PullRequest
1 голос
/ 31 января 2009

Я пытаюсь создать кеш в веб-сервисе. Для этого я создал новый компонент без сохранения состояния, чтобы предоставить этот кеш другим компонентам без сохранения состояния. Этот кеш является просто статическим ConcurrentMap, где MyObject является POJO. Проблема в том, что кажется, что существуют разные объекты кеша. Один для клиентских компонентов, а другой локально.

-CacheService
-CacheServiceBean
  -getMyObject()
  -insertMyObject(MyObject)
  -size()

-SomeOtherBean
 cache = jndiLookup(CacheService)
 cache.insertMyObject(x)
 cache.size() -> 1

После этого назначения, если я вызываю cache.size из CacheServiceBean, я получаю 0. Можно ли даже поделиться статическими синглетонами через бобы? Наконец я решил использовать таблицу базы данных, но я все еще думаю об этом.

Спасибо за ваши ответы.

Ответы [ 5 ]

4 голосов
/ 31 января 2009

Насколько я помню, вы не можете быть уверены, что bean-компонент без состояния достаточно глобален, чтобы хранить данные в статических полях. Существует несколько рамок кэширования, которые помогут вам в этом. Может быть memcache ?

EDIT: http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html#static_fields говорит:

Нефинальные статические поля запрещено в EJB, потому что такие поля сделать боб предприятия трудным или невозможно распространить

3 голосов
/ 31 января 2009

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

1 голос
/ 10 августа 2011

Я знаю, что это сообщение было некоторое время назад, но, похоже, появился новый Синглтон-Бин, который будет отвечать требованиям кеша, к которому стремился исходный вопрос:

http://download.oracle.com/javaee/6/tutorial/doc/gipjg.html

Сессионные EJB-компоненты синглтона предлагают функциональность, аналогичную сессионным EJB-компонентам без сохранения состояния, но отличаются от них тем, что в приложении имеется только один сессионный EJB-компонент, в отличие от пула сессионных EJB-компонентов без состояния, каждый из которых может отвечать на запрос клиента. Как и сеансовые компоненты без сохранения состояния, одноэлементные сеансовые компоненты могут реализовывать конечные точки веб-службы.

Я пытался создать его и ссылаться на него из-за проблем с компонентом WebService / Stateless. работал как рекламируется.

1 голос
/ 31 января 2009
@Stateless
public class CacheSessionBean implements CacheSessionLocal {
    private static Map<String, Object> cacheMap = new HashMap<String, Object>();

    public Object getCache(String key) {
        return cacheMap.get(key);
    }

    public void putCache(String key, Object o) {
        cacheMap.put(key, o);
    }
}

Предостережения относительно распределения EJB-компонентов в кластере применяются к статическим переменным. Однако, если вы не кластеризуетесь, они в значительной степени к вам не относятся, поэтому на этом уровне статика - «окей докей».

У вас будут проблемы с синхронизацией.

Один из способов смягчения - настройка контейнера для создания и объединения в пул только одного экземпляра компонента CacheSession, тогда контейнер будет управлять этой синхронизацией за вас.

Вы также можете управлять синхронизацией самостоятельно, но вы не должны делать это на уровне метода EJB, скорее всего, вам лучше иметь синхронизированный объект Cache (по сравнению, скажем, с универсальным HashMap).

Но ключ к этому моменту в том, что статические переменные - это просто статические переменные.

Теоретически, вам необходимо быть осведомленным о жизненном цикле контейнера для вашего сессионного компонента (поскольку он может потенциально освобождать все экземпляры и, следовательно, фактический класс компонента может иметь право на сборщик мусора, что может привести к потере любых статических данных). Однако на практике, если услуга популярна, это вряд ли произойдет. Но, к вашему сведению, это МОЖЕТ БЫТЬ.

1 голос
/ 31 января 2009

При использовании bean-компонентов без сохранения состояния вы не можете контролировать количество их экземпляров (это зависит от сервера приложений). Вы могли бы получить выходные данные от другого компонента, отличного от того, который вы искали у своего клиента. Вы напечатали это в своем журнале? В этом случае, возможно, вы должны были увидеть более одного выхода. Суть в том, что вы не можете знать, какой экземпляр вы получаете, когда просматриваете bean-компонент без состояния через jndi (вы просто получаете один). И у вас нет состояния, поэтому я не знаю, является ли это лучшим выбором для кэша.

Под статическим одноэлементным я полагаю, вы имеете в виду одноэлементный объект? Да, это не должно быть проблемой для доступа к синглтону через множество компонентов. Но помните о проблемах параллелизма, которые вы, вероятно, получите. Сервер приложений (бобы в целом) много от вас абстрагирует.

...