Гарантирует ли спецификация сервлета инициализацию одного потока и встроенные события attributeChanged? - PullRequest
2 голосов
/ 05 января 2012

У меня есть веб-приложение, которое загружает получатель событий из внешней системы при инициализации ServletContext. Все компоненты, которые должны получать события, прослушивают события атрибута ServletContext и присоединяются как слушатели. Поскольку я не хочу, чтобы прослушиватели событий пропускали события, я хочу запускать источник событий только после того, как все прослушиватели были подключены.

Я не смог найти какие-либо требования к потокам для инициализации в спецификации Servlet 2.5 и 3.0, поэтому я предполагал полностью асинхронную модель инициализации, но я заметил, что Tomcat запускает события изменения атрибута ServletContext непосредственно из метода setAttribute (). Это будет означать, что если все другие контейнеры сервлетов последуют их примеру, я могу упростить процедуру запуска.

РЕДАКТИРОВАТЬ: В соответствии с просьбой, вот пример (я пытался быть как можно более конкретным). В моем web.xml я в настоящее время зарегистрировался:

  • BootstrapEventSourceContextListener при инициализации контекста сервлета:
    1. создает событие-источник и устанавливает его в качестве атрибута контекста сервлета.
    2. источник событий в данный момент не запускается (т.е. он не генерирует события)
  • ConsumerAContextAttributeListener при получении уведомления о том, что установлен атрибут, содержащий источник события:
    1. ищет источник события из атрибута servlet-context
    2. создает экземпляр ConsumerA
    3. присоединяет ConsumerA к источнику событий
    4. устанавливает модель данных ConsumerA в качестве атрибута в контексте сервлета
  • ConsumerBContextAttributeListener - так же, как Comsumer A
  • ConsumerCContextAttributeListener - так же, как A и B, за исключением того, что он также зависит от модели данных B
  • StartEventSourceFilter при доступе к странице:
    1. ищет источник событий из контекста сервлета
    2. запускает источник событий
    3. блоков до тех пор, пока источник событий не получит начальный снимок
    4. продолжает отображать страницу

Вопрос в том, действительно ли мне нужен StartEventSourceFilter, или он гарантированно присоединится ко всем потребителям, как только я установлю атрибут источника-события (т.е. прослушиватели атрибута не будут отложены). Я забочусь о Tomcat, Jetty и Websphere.

1 Ответ

2 голосов
/ 12 января 2012

Поскольку никто не ответил, я закопался, и вот что я нашел:

В спецификации Servlet 3.0 не указывается, уведомляются ли слушатели встроенно или асинхронно, но в главе 11 предусмотрены следующие гарантии:

  • 11.2 Все слушатели, имеющие право обрабатывать определенное событие, вызываются в порядке их регистрации в web.xml
  • 11.5 Слушатели жизненного цикла ServletContext будут созданы перед контейнером, обслуживающим его первый запрос. Не существует явной спецификации потоков, но, учитывая, что вышеприведенный пункт гарантирует порядок, я предполагаю, что это означает, что они также будут вызываться последовательно и синхронно (дождитесь завершения текущего экземпляра, прежде чем вызывать следующий) - скорее всего, это означает тот же поток , Также не указано явно, но я считаю разумным предположить, что контейнер будет ожидать завершения всех методов уведомления, прежде чем обслуживать первый запрос. Подтвердили, что именно этим занимаются Tomcat и Jetty.
  • 11.5 Изменения атрибутов в ServletContext и сеансе HTTP могут выполняться одновременно. Учитывая, что здесь также упоминается сеанс HTTP, я понимаю, что если сервлеты изменяют контекст, эти изменения могут выполняться одновременно. В нашем случае прослушиватели контекста изменяют атрибуты контекста, и, как и в предыдущем пункте, мы заявили, что они работают синхронно, и, поскольку требование упорядочения выполняется для прослушивателей ctx-атрибутов, мы можем предположить, что прослушиватели атрибутов во время инициализации выполняются последовательно.

Единственная оставшаяся проблема заключается в том, всегда ли прослушиватели атрибутов контекста сервлета всегда выполняются в строке с установщиками, или есть реализации, которые ставят их в очередь (скажем, для объединения нескольких событий изменения для одного и того же атрибута). Я полагаю, что разумно предположить, что намерение спецификации и всех реализаций уведомит встроенных слушателей (и подтвердит это для Tomcat и Jetty).

Итог: при установке атрибута контекста из прослушивателя context-init вполне разумно предположить, что все прослушиватели атрибута context завершат, когда вернется метод setter. Спецификация явно не гарантирует этого, но все указанные ограничения и гарантии указывают в этом направлении.

...