Вопрос

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

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

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

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

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

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

Решение

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

Редактировать:http://java.sun.com/blueprints/qanda/ejb_tier/restrictions.html#static_fields говорит:

Поля нефинального статического класса запрещены в EJBS, поскольку такие поля затрудняют или делают невозможным распространение корпоративного компонента

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

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

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

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

@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, скорее всего, вам было бы лучше иметь синхронизированный объект кэша (по сравнению, скажем, с общим HashMap).

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

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

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

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

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

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

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