Инъекция 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;
%>

Это работает для меня:)

Примечание: используйте скобку <%! %> вместо <% %> ,

Другие вопросы по тегам