2009-03-06 1 views
11

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

Мой вопрос: безопасно ли вводить EJB с помощью аннотации @EJB в сервлет как переменную экземпляра?

Мой первоначальный инстинкт не был бы, если предположить, что тот же экземпляр EJB будет обслуживать несколько запросов одновременно. Казалось бы, это было бы также инстинктом ряда других программистов: Don't inject to servlets

Однако я подпрыгнул с неверного вывода. Очевидно, что что вводится в сервлет, является прокси, под капотом действительно ли контейнер обслуживает каждый запрос другим экземпляром и поддерживает безопасность потоков? Как этот форум предложил бы: Do inject to servlets

Кажется, что существует много противоречивых мнений. ЧТО ПРАВИЛЬНО???

ответ

3

Ваша ссылка «Не вводить в сервлеты» ничего не упоминает о ejbs или аннотации @ejb. В нем говорится о небезопасных объектах, таких как PersistenceContext.

В спецификации EJB вы можете получить доступ к ejbs из множества удаленных клиентов, включая сервлеты (спецификация EJB 3.0 (JSR-220) - раздел 3.1). Инъекция ejb с использованием аннотации @EJB - это метод получения интерфейса EJB через инъекцию зависимостей (раздел 3.4.1), который является альтернативой поиску объектов ejb в пространстве имен JNDI. Поэтому нет ничего особенного в @EJB-аннотации относительно полученных EJB.

Итак, на основе EJB 3.0 Spec стандартная практика заключается в получении ejbs из сервлетов с использованием аннотации @EJB.

+0

Этот ответ верный, насколько это возможно, но он не касается проблем безопасности потоков OP. Я считаю, что нижеприведенный ответ нижеследующего должен быть правильным. –

+0

Я предполагаю, что EJB, инъецированный с помощью @Inject (CDI, JEE 6), будет таким же безопасным, не так ли? – marcus

0

Я думаю, что простой ответ заключается в том, что вы не гарантированы, что это безопасно.

Причина в том, что в спецификации EJB нет ничего явного, в котором говорится, что домашние интерфейсы EJB должны быть потокобезопасными. Спецификация описывает поведение только части сервера. Вероятно, вы обнаружите, что скелеты клиента фактически потокобезопасны, но вам нужно будет посмотреть, как они реализованы библиотекой, которую вы используете. Часть аннотации будет просто расширяться в локатор сервисов, чтобы вы ничего не покупали.

11

Безопасно вводить EJB в сервлет как переменную экземпляра сервлета, если EJB не имеет статуса. Вы ДОЛЖНЫ НИКОГДА не вводить Stateful Bean в сервлете.

Вы должны реализовать свой EJB без гражданства в том, что он не содержит никакой переменной экземпляра, которая сама содержит значение состояния (например, Контекст сохранения). Если вам нужно использовать контекст персистентности, вы должны получить его экземпляр в методах EJB. Вы можете сделать это, имея PersistenceContextFactory в качестве переменной экземпляра EJB, а затем вы получите экземпляр менеджера сущностей из Factory в методе EJB.

PersistenceContextFactory является потокобезопасным, поэтому его можно вводить в переменную экземпляра.

Пока вы согласны с указанными выше правилами, она должна быть поточно-придать Stateless Bean в Servlet

1

Это смешанный мешок.

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

Я думаю, что указано в indesreddesign, это не верно. Не имеет значения, использует ли сеансовый компонент без состояния постоянный контекст. Только один вызывающий абонент будет одновременно обращаться к одному экземпляру компонента, поэтому, хотя контекст сохранения не является потокобезопасным, EJB защищает от множественного доступа к нему. Подумайте об этом, как если бы каждый метод bean-сеанса применял к нему синхронизированное ключевое слово.

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

+0

Штук будет синхронизирован, но я ожидаю, что он быстро отправит в один из объединенных EJB, чтобы выполнить настоящую работу. Если заглушка не удерживает замок во время всего вызова, что было бы очень плохим выбором реализации ... – marcus

Смежные вопросы