Передача состояния между методами EJB / @RequestScoped и @Stateless - PullRequest
8 голосов
/ 03 января 2012

У меня есть бин CDI @RequestScoped, который я хочу превратить в EJB для получения декларативных транзакций.(Я нахожусь на EJB 3.1, Java EE 6)

В настоящее время я передаю состояние между подпрограммами, предполагая, что экземпляр используется только в одном запросе.Если я добавлю @Stateless сейчас, это предположение изменится.

Например, я хочу сделать что-то вроде

@Stateless
@Named
@RequestScoped
public class Foo {
  private String var1; // can't use instance vars in @Stateless?
  private String var2;

  public void transactionForRequest() {
    var1 = value; 
    var2 = value;
    ....
    subroutine();
  }
}

Я предполагаю, что вышеописанное не работает - это правильно?

Я рассматриваю две альтернативы:

  • Используйте @Stateful вместо @Stateless вместе с @Named и @RequestScoped.
  • Оставьте @Stateless и используйте EJBContext.getContextData map для замены переменных экземпляра.

Что лучше?И есть ли какая-то другая альтернатива, о которой я не думаю?(Кроме того, дождитесь Java EE 7 или переключитесь на Spring.: -))

Ответы [ 3 ]

12 голосов
/ 04 января 2012

Хотя @Stateless, @Singleton и @MessageDriven могут иметь ссылки области действия, введенные через @Inject, они не могут быть @RequestScoped или любой другой областью действия.Только модель @Stateful достаточно гибкая для поддержки областей.Другими словами, вы можете аннотировать сам класс EJB @Stateful как @RequestScoped, @SessionScoped и т. Д.

Проще говоря, @Stateless, @Singleton уже исправили "области видимости".@Singleton - это, по сути, @ApplicationScoped, и @Stateless, возможно, будет некоторой выдуманной областью, такой как @InvocationScoped, если бы она существовала.Жизненный цикл bean-компонента @MessageDriven полностью зависит от Connector, который управляет им, и поэтому также не может иметь определяемую пользователем область.

См. Также https://stackoverflow.com/a/8720148/190816

3 голосов
/ 03 января 2012

Я бы пошел с SFSB вместо SLSB. Вы хотите удерживать государство, поэтому для меня это самая важная информация - это работа для Stateful EJB.

Также я не думаю, что EJBContext#getContextData() поможет вам. Насколько я помню, это действует только на время разговора. Поэтому каждый вызов метода в вашем EJB создаст новую карту данных контекста (по крайней мере, это то, что я ожидал).

1 голос
/ 03 января 2012

Если вы используете компоненты без состояния, то вы несете ответственность за любое управление состоянием, и вы обычно делаете это на уровне веб-приложений, используя HttpSessions. И да, вы не можете использовать переменные экземпляра, так как бины без состояния объединяются.

...