В EJB-банке, куда поместить код для выполнения только один раз при инициализации? - PullRequest
2 голосов
/ 28 ноября 2011

Что мне нужно: место внутри EJB JAR для размещения кода, который считывает и кэширует данные конфигурации из источника с высокой степенью латентности (например, из БД с медленным соединением). В идеале я бы хотел, чтобы контейнер гарантировал, что этот код будет выполнен только один раз.

ОБНОВЛЕНИЕ: мы используем EJB 3.0, поэтому @Singleton не вариант. Методы @PostConstruct имеют один недостаток: они выполняются один раз в течение жизненного цикла компонента, поэтому каждый раз, когда создается компонент, выполняется наш медленный код. Вместо этого я хотел бы прочитать данные только один раз при запуске application и кэшировать их.

Чтобы дать некоторый контекст: в веб-приложениях Java я привыкла помещать свой код инициализации в метод SessionContextListener.contextInitialized(). Согласно спецификации сервлета JSR 154 (разделы SRV.9.12, SRV.15.2.12.1), этот метод вызывается до инициализации любого фильтра или сервлета в веб-приложении и, что более важно, вызывается только один раз для данного слушатель.

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

У вас, ребята, есть идеи, куда поместить этот код 'read config' в EJB JAR? Или, возможно, другие подходы к чтению и кешированию данных конфигурации в многопоточных средах?

Спасибо всем.

Ответы [ 3 ]

1 голос
/ 28 ноября 2011

Используйте синглтон EJB.См. http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html.

Вы можете инициализировать его с энтузиазмом или ленивостью.

0 голосов
/ 28 ноября 2011

Поместите метод в @PostConstruct в EJB , как показано ниже.

@PostConstruct
public void init()
{
    //Some EJB stuff.
}

Метод init() будет выполнен только один раз, когда ваш EJB загружено.

0 голосов
/ 28 ноября 2011

Вы можете поместить код в блок static { } в любом классе, и он будет загружен только один раз для загрузчика классов .

Вы можете определить объект Singleton с помощью private конструктор и static метод, который возвращает только один экземпляр этого класса.Это также относится к один раз для загрузчика классов предостережение.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...