При использовании @EJB каждый управляемый bean получает свой собственный экземпляр @EJB?

Я использую JSF 2.2 для веб-проекта, и теперь я реализую страницу входа.

У меня есть login.xhtml, который служит как view, а подкачка bean называется UserLoginView.
Этот bean имеет свойство EJB bean private UserService userService (как показано здесь).

Означает ли это, что каждый новый UserLoginView получает новый экземпляр UserService?

В порядке ли реализовать его в рабочей среде?

Ответы

Ответ 1

  Означает ли это, что каждый новый UserLoginView получает новый экземпляр UserService?

Нет. Данный UserService является @Stateless EJB. @Stateless EJB объединяются и вводятся как сериализуемые прокси, автоматически генерируемые контейнером. Среди прочего, доказательством этого является трассировка стека при возникновении исключения из EJB. Вы видите дополнительные слои между методом базового компонента и методом EJB.

Автоматически сгенерированный прокси-класс для EJB @Stateless выглядит примерно так (на самом деле он более сложный, например, транзакция БД также должна быть получена, запущена и зафиксирована здесь в зависимости от @TransactionAttribute класса EJB и/или метода):

public class UserServiceProxy extends UserService implements Serializable {

    public User find(Long id) {
        UserService instance = getAnAvailableInstanceFromPool();
        User result = instance.find(id);
        releaseInstanceToPool(instance);
        return result;
    }

    public Long save(User user) {
        UserService instance = getAnAvailableInstanceFromPool();
        Long result = instance.save(user);
        releaseInstanceToPool(instance);
        return result;
    }

    // ...
}

Ты видишь это? Он просто получает доступный экземпляр из пула EJB, а затем делегирует ему вызов метода и, наконец, передает его в пул для повторного использования в будущем. Это именно тот экземпляр прокси, который фактически внедряется в ваш управляемый компонент JSF.

Кстати, CDI работает так же. Именно поэтому с помощью CDI можно внедрить бин более узкой области в боб более широкой области действия и все же заставить его работать так, как задумано. JSF @ManagedBean внедряет фактический экземпляр, и поэтому он не работает таким образом. Это сработало бы, если бы JSF также использовал прокси, которые фактически захватывали текущий экземпляр компонента через FacesContext и делегировали ему.

Только EJB @Stateful фактически привязаны к времени жизни клиента. В случае управляемого компонента в качестве клиента он действительно получит "свой" экземпляр. См. также bean-объект в области JSF-запросов продолжает воссоздавать новые сеансовые bean-компоненты Stateful при каждом запросе?

И @Singleton EJB имеют в основном максимум один экземпляр в пуле. Таким образом, каждый клиент всегда получит один и тот же экземпляр.


Можно ли это реализовать в производственной среде?

Абсолютно. Иначе их не было.