Вызов метода производителя области действия сеанса CDI из EJB-компонента без состояния - PullRequest
7 голосов
/ 07 августа 2011

Я хочу внедрить текущего пользователя, используя @Inject @Current User для всех слоев (т. Е. Веб-слой, слой EJB).Для этого у меня есть следующий метод CDI Producer:

@Named
@SessionScoped
public class UserController {
   @Resource SessionContext sessionContext;
   @EJB UserDao userDao;

   @Produces @Current
   public User getCurrentUser() {
     String username = sessionContext.getCallerPrincipal().getName();
     User user = userDao.findByUsername(username);
   }
}

@Qualifier
@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface Current{}

Теперь я хочу внедрить текущего пользователя в сессионный компонент EJB без сохранения состояния следующим образом:

@Stateless
public class SomeBackendService {
   @Inject @Current
   private User user;
}

Мой вопрос: всегда ли текущий объект пользователя повторно вводится после изменений сеанса, потому что зависимости сессионного компонента без сохранения состояния обычно вводятся один раз во время создания, и этот компонент может быть объединен и использован в разных сеансах?

Ответы [ 3 ]

4 голосов
/ 07 августа 2011

Хотя я не пробовал эту точную ситуацию , в бобах CDI обычно не вводятся повторно.Вместо этого вводится прокси-сервер, который знает о своем контексте.

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

Так что, хотя область действия @Statelessв основном это «приложение», возможно, что прокси, который представляет User в вашем SomeBackendService, все еще делегирует правильную версию сессий.

ps

Если с Слои Вы на самом деле имеете в виду модули, как в веб-модулях, так и EJB-модули, которые являются частью EAR, это будет немного сложнее, так как CDI не всегда работает должным образом между модулями (особенно в JBoss AS).Отчасти это связано с неоднозначностью того, что такое «приложение» и, следовательно, область применения находится в EAR.

1 голос
/ 05 сентября 2013

Да, в каждый бизнес-метод, называемый контейнером, будут повторно внедрены все зависимости вашей SLSB.Вот текст, который гарантирует это в спецификации EJB 3.1:

"Если сессионный компонент использует внедрение зависимостей, контейнер внедряет эти ссылки после создания экземпляра компонента и до вызова любых бизнес-методов в компоненте.пример."- Раздел 4.3.2

У меня тоже было это сомнение, и я разместил вопрос, объясняющий эту ситуацию здесь

1 голос
/ 06 марта 2013

По своей сути ваш сессионный компонент без сохранения состояния не должен иметь состояния «Пользователь», это обязательно состояние без сохранения состояния.

Если вы хотите, чтобы у вашего EJB были состояния, вместо этого используйте @Stateful.

...