четверг, 24 февраля 2011 г.

Listeners (хм .. Слушатели)

Для начала разобьём эту тему на под темы:
1. Listeners (Непосредственно слушатели).
2. Подключение слушателей
3. События и слушатели
4. Резюме

Listeners

Существует достаточно большое разнообразие Listener-ов. Для систематизации разделим их на несколько групп:

1. Attributes Listener (Слушатель Атрибутов)

2. Servlet Life-Cycle Events and Listener (События и слушатели жизненного цикла сервлета)


Attributes Listener (Слушатель Атрибутов) 
В зависимости от контекста (scope) различают следующих Listener-ов:

Request Scope (Контекст запроса): 
                  ServletRequestAttributeListener (javax.servlet)
Session Scope (Контекст сессии)
                  HttpSessionAttributeListener (javax.servlet.http)
                  HttpSessionBindingListener (javax.servlet.http)
                  HttpSessionActivationListener (javax.servlet.http)
Context Scope (Контекст сервлет контекста):  
                  ServletContextAttributeListener (javax.servlet)

javax.servlet.ServletRequestAttributeListener
Этот Listener используется при "слушании" событий происходящих с атрибутами  запроса.

Метод                                                                                           Описание                          _
void attributeAdded(ServletRequestAttributeEvent srae)            Вызывается когда атрибут 
                                                                                                      добавляется в запрос

void attributeRemoved(ServletRequestAttributeEvent srae)        Вызывается когда атрибут 
                                                                                                       удаляется из запроса

void attributeReplaced(ServletRequestAttributeEvent srae)        Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                              _


 javax.servlet.http.HttpSessionAttributeListener
Этот Listener используется для "слушания" событий происходящих с атрибутами в сессии.
 Метод                                                                                          Описание                           _
void attributeAdded(HttpSessionBindingEvent se)                      Вызывается когда атрибут 
                                                                                                      добавляется в сессию

void attributeRemoved(HttpSessionBindingEvent se)                  Вызывается когда атрибут 
                                                                                                       удаляется из сессии

void attributeReplaced(HttpSessionBindingEvent se)                  Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                              _

javax.servlet.http.HttpSessionBindingListener
Этот Listener так-же используется для прослушивания событий происходящих с атрибутами в сессии. Разница между HttpSessionAttributeListener и HttpSessionBindingListener
HttpSessionAttributeListener: декларируется в web.xml (декларирование см ниже), экземпляр класса создается автоматически (контейнером) в единственном числе  и применяется ко всем сессиям
HttpSessionBindingListener: экземпляр этого класса должен быть создан и закреплён за определённой сессией программистом "вручную", количество экземпляров регулируется программистом.
 Метод                                                                                          Описание_                     _
void valueBound(HttpSessionBindingEvent se)                           Вызывается когда объект
                                                                                                     добавляется в сессию

void valueUnbound(HttpSessionBindingEvent se)                       Вызывается когда объект
                                                                                                     удаляется из сессии
_                                                                                                                                              _

javax.servlet.http.HttpSessionActivationListener 
Этот Listener используется атрибутами сессии в случае, если сессия будет "мигрировать" между различными JVM в распределённых приложениях.
 Метод                                                                                     Описание                              _
void sessionWillPassivate(HttpSessionEvent se)                     Вызывается перед тем, как сессия                                                                                                 станет пассивной перед миграцией

void sessionDidActivate(HttpSessionEvent se)                       Вызывается после того, как сессия   
                                                                                                 стала активной после миграции
_                                                                                                                                              _

javax.servlet.ServletContextAttributeListener
 Этот Listener используется для "слушания" событий, происходящих с атрибутами в сервлет контексте (ServletContext).
Метод                                                                                          Описание                              _
void attributeAdded(ServletContextAttributeEvent scae)          Вызывается когда атрибут 
                                                                                                    добавляется в ServletContext

void attributeRemoved(ServletContextAttributeEvent scae)      Вызывается когда атрибут 
                                                                                                    удаляется из ServletContext-a 

void attributeReplaced(ServletContextAttributeEvent scae)       Вызывается когда атрибут меняет
                                                                                                      значение
_                                                                                                                                                  _

 Servlet Life-Cycle Events and Listener (События и слушатели жизненного цикла сервлета)

К слушателям событий жизненного цикла относятся следующие Listener-ы:
     ServletContextListener (javax.servlet)
     HttpSessionListener (javax.servlet.http)
     ServletRequestListener (javax.servlet)

 javax.servlet.ServletContextListener
Этот Listener позволяет разработчику "уловить" момент когда ServletContext инициализируется либо уничтожается. Его можно использовать, например, для открытия соединения с базой данных в момент создания контекста и закрытия соединения в момент уничтожения контекста.
Метод                                                                                          Описание                             _
void contextDestroyed(ServletContextEvent sce)                   Вызывается перед тем как ServletContext 
                                                                                                   будет уничтожен

void contextInitialized(ServletContextEvent sce)                   Вызывается сразу после создания
                                                                                                      ServletContext-a 
_                                                                                                                                                  _


javax.servlet.http.HttpSessionListener
Этот Listener позволяет разроботчику "уловить" момент создания и уничтожения сессии.

Метод                                                                                          Описание                               _
void sessionCreated(HttpSessionEvent se)                              Вызывается когда сессия создается

void sessionDestroyed(HttpSessionEvent se)                           Вызывается когда сессия уничтодается
_                                                                                                                                                   _

 javax.servlet.ServletRequestListener 
Этот Listener используется, соответственно, для того, чтоб "уловить" момент создания и уничтожения запроса.

Метод                                                                                          Описание                               _
void requestDestroyed(ServletRequestEvent se)                       Вызывается когда запрос уничтожается 

void requestInitialized(ServletRequestEvent se)                       Вызывается когда запрос инициализируется
_                                                                                                                                                   _

Подключение слушателей
Для описания того, как подключить Listener-ов обратимся с перво истокам web.xml-я, а именно к web-app_2_3.dtd взятых вот здесь

Root-овый элемент web-app:

<!ELEMENT web-app (icon?, display-name?, description?, distributable?, context-param*, filter*, filter-mapping*, listener*, servlet*, servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?, error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*, login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>

и соответственно сам элемент listener:

<!ELEMENT listener (listener-class)>

где listener-class: 

<!ELEMENT listener-class (#PCDATA)>

То есть можно добавлять любое количество listener-ов непосредственно в root-овый элемент web-app причём элемент listener обязан содержать 1 элемент - listener-class. 
Пример: 

<web-app>
    ...
    <listener>
        <listener-class>my.some.path.MyListenerClass</listener-class>
    </listener>
    <listener>
        <listener-class>my.some.other.path.MyOtherListenerClass</listener-class>

    </listener>
    ...
</web-app>

Отдельно стоит рассмотреть HttpSessionBindingListener, так как он подключается непосредственно в сессию в качестве атрибута. Тоесть, чтоб подключить этот listener необходимо: 
 - создать экземрляр класса реализующего этот интерфейс
 - положить созданый экземпляр в сессию при помощи setAttribute(String, Object)

Пример: 
Допустим есть класс наследующий HttpServlet с переопределённым методом doGet


public void doGet(HttpServletRequest req, HttpServletResponse resp) {
...
    MyInstanceOfHttpSessionBindingListener miohsbl = new MyInstanceOfHttpSessionBindingListener();
    HttpSession session = req.getSession();
    req.setAttribute("anyName", miohsbl);             <---- A
...
    req.setAttribute("anyName", new Object());     <---- B
....
{


метод valueBound класса MyInstanceOfHttpSessionBindingListener будет вызван в момент A, a метод valueUnbound в момент B.

События и слушатели
Соберём всё события и слушатели в одну "таблицу" :
Listener                                              Event                                           Самые значимые методы Event _
ServletRequestAttributeListener       ServletRequestAttributeEvent        public String getName()
                                                                                                              public Object getValue()

HttpSessionAttributeListener            HttpSessionBindingEvent               public String getName()
                                                                                                              public Object getValue()
                                                                                                              public HttpSession getSession()

HttpSessionBindingListener              HttpSessionBindingEvent               public String getName()
                                                                                                              public Object getValue()
                                                                                                              public HttpSession getSession()

HttpSessionActivationListener         HttpSessionEvent                            public HttpSession getSession()

ServletContextAttributeListener      ServletContextAttributeEvent        public String getName()
                                                                                                              public Object getValue()

ServletContextListener                     ServletContextEvent                      public ServletContext getServletContext()

HttpSessionListener                          HttpSessionEvent                           public HttpSession getSession()

ServletRequestListener                     ServletRequestEvent                      public ServletContext getServletContext()
                                                                                                              public ServletRequest getServletRequest()
 _                                                                                                                                                               _


Для простоты запоминаная: практически все пары listener\event имеют название ...Listener \ ...Event (ServletContextListener \ ServletContextEvent ... ) за 2-я исключениями: 
- HttpSessionAttributeListener, который в качестве параметра принимает HttpSessionBindingEvent 
- HttpSessionActivationListener, который принимает HttpSessionEvent              

Резюме
 - Cуществует множество задач решение которых станет (или уже стало) более простое и элегантное с применением listener-ов. 
 - Ещё одним удобным способом разбиения listener-ов на группы является разбиение исключительно по принципу контекста (scope):
Request:
    ServletRequestListener
    ServletRequestAttributeListener
Context
    ServletContextListener
    ServletContextAttributeListener

Session
    HttpSessionListener                  
    HttpSessionAttributeListener         
    HttpSessionBindingListener           
    HttpSessionActivationListener


Комментариев нет:

Отправить комментарий