Инъекция CDI в JSP
В JSP можно использовать управляемые компоненты CDI, используя выражения EL, такие как ${myBean.myAttribute}. Здесь нет проблем.
Я хотел бы использовать "регулярное внедрение" (т.е. без использования выражений EL) с @Inject в файлах JSP, например:<%! @ Inject MyBean myBean; %> затем позже <% = myBean.getMyAttribute ()%>. Даже если этот пример может быть достигнут с помощью выражений EL, некоторые другие варианты использования не могут.
Похоже, это не полностью поддерживается серверами приложений:
- JBoss 6.0.0, JBoss 6.1.0, Resin 4.0.22: ОК, все работает отлично.
- JBoss 7.0.1, GlassFish 3.x (было протестировано несколько версий): СБОЙ, myBean остается нулевым.
Это должно хорошо работать в JSP, так как:
(1) он отлично работает в сервлетах в соответствии с различными соответствующими спецификациями и
(2) JSP переводится в сервлет во время выполнения.
Ребята, вы знаете, поддерживается или нет то, что я пытаюсь сделать? Может быть, есть какая-то информация о внутренней реализации?
С наилучшими пожеланиями.
Спасибо за ваше время.
2 ответа
Интересный вопрос, если бы вы не тестировали его, я бы поставил немного денег на тот факт, что он не работает;-)
CDI основан на управляемых компонентах (JSR 316). Соответствующее определение довольно смягчено (нарочно):
Из спецификации:
Управляемый компонент может быть объявлен путем аннотирования его класса аннотацией javax.annotation.ManagedBean. Управляемый компонент не должен быть: конечным классом, абстрактным классом, нестатическим внутренним классом. Управляемый компонент не может быть сериализуемым, в отличие от обычного компонента JavaBean.
В базовой модели компонентов управляемые компоненты должны предоставлять конструктор без аргументов, но спецификация, основанная на управляемых компонентах, такая как CDI (JSR-299), может ослабить это требование и позволить управляемым компонентам предоставлять конструкторам более сложные сигнатуры,
Вероятно, происходит то, что контейнер сканирует путь к классам и обнаруживает скомпилированные сервлеты JSP. Прошло много времени с тех пор, как я последний раз видел один, но я помню, что код генерируется и все (включая скриптлеты) попадает в doGet()
или же doPost()
...!? Таким образом, даже если они формально не дисквалифицируются с точки зрения определения, я сомневаюсь, что сценарий JSP - это то, что вы хотите считать управляемым компонентом. Честно говоря, это ужасно неправильно;-)
Я давно следил за списками рассылки CDI / Weld / Seam, и не помню, чтобы JSP когда-либо упоминался. То же самое с поиском этой связи.
Как следствие, вы не должны полагаться на CDI, работающий со скриплетами. ИМХО, такое поведение имеет больше побочного эффекта, чем интенционального, и может быть отброшено в будущих выпусках без уведомления (или даже без уведомления:-)
Итак, +1 за предложение JB Nizet: использовать сервлеты с CDI, но не JSP.
ОБНОВЛЕНИЕ: Я пытался помочь, а не создавать путаницу;-) Моя точка зрения: ИМХО, это действительно очень неправильно использовать CDI в JSP, но я не нашел ничего в соответствующих спецификациях, подтверждающих это. Все, что я могу сказать, это то, что JSPникогда нигде не упоминаются - что поддерживает мои интуитивные ощущения (и соответствует наблюдению, что некоторые реализации учитывают это, а другие нет).
Я не думаю, что есть портативный @Inject, доступный для JSP, но должна быть возможность реализовать его (на уровне контейнера) так же, как он работает с сервлетами.
И хотя я согласен, что это не лучший способ использовать CDI, технически я не вижу в этом никакой причины. Например, AFAIK @Inject в сервлетах прозрачно использует прокси ThreadLocal, почему бы не использовать эту функцию в JSP?
Попробуй это:-
<%!
@Inject
private UserService userService;
%>
Это работает для меня:)
Примечание: используйте скобку <%! %>
вместо <% %>
,