Безопасно ли вводить EJB в сервлет как переменную экземпляра?
-
03-07-2019 - |
Вопрос
Все мы знаем, что на веб-уровне существует вероятность того, что существует только один экземпляр данного сервлета, который обслуживает несколько запросов. Это может привести к проблемам с многопоточностью в переменных экземпляра.
Мой вопрос: безопасно ли внедрять EJB-компонент, используя аннотацию @EJB в сервлете в качестве переменной экземпляра?
Мой первоначальный инстинкт был бы отрицательным, при условии, что один и тот же экземпляр EJB будет обслуживать несколько запросов одновременно. Казалось бы, это также было бы инстинктом ряда других программистов: Не вводите в сервлеты
Однако я сделал неверный вывод. Понятно, что в сервлет вводится прокси-сервер. Контейнер фактически обслуживает каждый запрос с другим экземпляром и поддерживает безопасность потоков? Как подсказывает этот форум: Делать инъекции в сервлеты
Кажется, что существует много противоречивых мнений. ЧТО ПРАВИЛЬНО ???
Решение
Ваша ссылка " Не вводить в сервлеты " ничего не упоминает о 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 стандартная практика - получать ejbs из сервлетов с помощью аннотации @EJB.
Другие советы
Безопасно внедрить EJB в сервлет как переменную экземпляра сервлета, если EJB не имеет состояния. Вы НИКОГДА НЕ ДОЛЖНЫ вводить Stateful Bean в сервлет.
Вы должны реализовать свой EJB без сохранения состояния, так как он не содержит никакой переменной экземпляра, которая сама содержит значение с состоянием (например, контекст постоянства). Если вам нужно использовать постоянный контекст, вы должны получить его экземпляр в методах EJB. Вы можете сделать это, имея PersistenceContextFactory в качестве переменной экземпляра EJB, а затем вы получите экземпляр диспетчера сущностей из Factory в методе EJB.
PersistenceContextFactory является поточно-ориентированным, поэтому его можно внедрить в переменную экземпляра.
До тех пор, пока вы соблюдаете вышеупомянутые правила, вводить компонент без сохранения состояния в сервлет должен быть ориентирован на многопотоковую обработку
Это смешанная сумка.
Сессионные компоненты без сохранения состояния могут быть введены и безопасны. Это связано с тем, что даже если используется один экземпляр заглушки, доступ к методам будет сериализован контейнером.
Я думаю, что inferreddesign не соответствует действительности . Не имеет значения, использует ли сессионный компонент без сохранения состояния постоянный контекст. Только один вызывающий пользователь может одновременно получить доступ к одному экземпляру bean-компонента, поэтому даже если контекст постоянства не является потокобезопасным, EJB защищает от множественного доступа к нему. Думайте об этом так, как будто к каждому методу сессионного компонента применяется ключевое слово synchronized.
Основная проблема с внедрением EJB в сервлет - это производительность. Один экземпляр-заглушка станет основной областью разногласий, когда несколько запросов стоят в очереди, ожидая, когда для них будет выполнен метод сессионного компонента.
Я думаю, что простой ответ заключается в том, что вам не гарантируется, что это безопасно.
Причина этого в том, что в спецификации EJB нет ничего явного, что домашние интерфейсы EJB должны быть поточно-ориентированными. Спецификация описывает поведение только серверной части. Вероятно, вы обнаружите, что клиентские скелеты на самом деле являются потокобезопасными, но вам нужно посмотреть, как они реализованы в используемой вами библиотеке. Часть аннотации просто превратится в сервисный локатор, так что вы ничего не купите. Р>