Listener 监听器
?
Listener 監(jiān)聽器
?
前言:之前寫了一篇關(guān)于Filter的文章:http://tianweili.github.io/blog/2015/01/26/java-filter/,現(xiàn)在再來一篇Listener的,Filter和Listener在項目中是經(jīng)常用到的,巧妙的使用可以達到事半功倍的效果。故把兩者的用法總結(jié)一下。
原文鏈接:http://tianweili.github.io/blog/2015/01/27/java-listener/
1、Listener的定義與作用
監(jiān)聽器Listener就是在application,session,request三個對象創(chuàng)建、銷毀或者往其中添加修改刪除屬性時自動執(zhí)行代碼的功能組件。
Listener是Servlet的監(jiān)聽器,可以監(jiān)聽客戶端的請求,服務端的操作等。
2、Listener的分類與使用
主要有以下三類:
1、ServletContext監(jiān)聽
ServletContextListener:用于對Servlet整個上下文進行監(jiān)聽(創(chuàng)建、銷毀)。
public void contextInitialized(ServletContextEvent sce);//上下文初始化 public void contextDestroyed(ServletContextEvent sce);//上下文銷毀public ServletContext getServletContext();//ServletContextEvent事件:取得一個ServletContext(application)對象ServletContextAttributeListener:對Servlet上下文屬性的監(jiān)聽(增刪改屬性)。
public void attributeAdded(ServletContextAttributeEvent scab);//增加屬性 public void attributeRemoved(ServletContextAttributeEvent scab);//屬性刪除 public void attributeRepalced(ServletContextAttributeEvent scab);//屬性替換(第二次設(shè)置同一屬性)//ServletContextAttributeEvent事件:能取得設(shè)置屬性的名稱與內(nèi)容 public String getName();//得到屬性名稱 public Object getValue();//取得屬性的值2、Session監(jiān)聽
Session屬于http協(xié)議下的內(nèi)容,接口位于javax.servlet.http.*包下。
HttpSessionListener接口:對Session的整體狀態(tài)的監(jiān)聽。
public void sessionCreated(HttpSessionEvent se);//session創(chuàng)建 public void sessionDestroyed(HttpSessionEvent se);//session銷毀//HttpSessionEvent事件: public HttpSession getSession();//取得當前操作的sessionHttpSessionAttributeListener接口:對session的屬性監(jiān)聽。
public void attributeAdded(HttpSessionBindingEvent se);//增加屬性 public void attributeRemoved(HttpSessionBindingEvent se);//刪除屬性 public void attributeReplaced(HttpSessionBindingEvent se);//替換屬性//HttpSessionBindingEvent事件: public String getName();//取得屬性的名稱 public Object getValue();//取得屬性的值 public HttpSession getSession();//取得當前的sessionsession的銷毀有兩種情況:
1、session超時,web.xml配置:
<session-config><session-timeout>120</session-timeout><!--session120分鐘后超時銷毀--> </session-config>2、手工使session失效
public void invalidate();//使session失效方法。session.invalidate();3、Request監(jiān)聽
ServletRequestListener:用于對Request請求進行監(jiān)聽(創(chuàng)建、銷毀)。
public void requestInitialized(ServletRequestEvent sre);//request初始化 public void requestDestroyed(ServletRequestEvent sre);//request銷毀//ServletRequestEvent事件: public ServletRequest getServletRequest();//取得一個ServletRequest對象 public ServletContext getServletContext();//取得一個ServletContext(application)對象ServletRequestAttributeListener:對Request屬性的監(jiān)聽(增刪改屬性)。
public void attributeAdded(ServletRequestAttributeEvent srae);//增加屬性 public void attributeRemoved(ServletRequestAttributeEvent srae);//屬性刪除 public void attributeReplaced(ServletRequestAttributeEvent srae);//屬性替換(第二次設(shè)置同一屬性)//ServletRequestAttributeEvent事件:能取得設(shè)置屬性的名稱與內(nèi)容 public String getName();//得到屬性名稱 public Object getValue();//取得屬性的值4、在web.xml中配置
Listener配置信息必須在Filter和Servlet配置之前,Listener的初始化(ServletContentListener初始化)比Servlet和Filter都優(yōu)先,而銷毀比Servlet和Filter都慢。
<listener><listener-class>com.listener.class</listener-class> </listener>3、Listener應用實例
1、利用HttpSessionListener統(tǒng)計最多在線用戶人數(shù)
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener;public class HttpSessionListenerImpl implements HttpSessionListener {public void sessionCreated(HttpSessionEvent event) {ServletContext app = event.getSession().getServletContext();int count = Integer.parseInt(app.getAttribute("onLineCount").toString());count++;app.setAttribute("onLineCount", count);int maxOnLineCount = Integer.parseInt(app.getAttribute("maxOnLineCount").toString());if (count > maxOnLineCount) {//記錄最多人數(shù)是多少app.setAttribute("maxOnLineCount", count);DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//記錄在那個時刻達到上限app.setAttribute("date", df.format(new Date()));}}//session注銷、超時時候調(diào)用,停止tomcat不會調(diào)用public void sessionDestroyed(HttpSessionEvent event) {ServletContext app = event.getSession().getServletContext();int count = Integer.parseInt(app.getAttribute("onLineCount").toString());count--;app.setAttribute("onLineCount", count); } }2、Spring使用ContextLoaderListener加載ApplicationContext配置信息
ContextLoaderListener的作用就是啟動Web容器時,自動裝配ApplicationContext的配置信息。因為它實現(xiàn)了ServletContextListener這個接口,在web.xml配置這個監(jiān)聽器,啟動容器時,就會默認執(zhí)行它實現(xiàn)的方法。
ContextLoaderListener如何查找ApplicationContext.xml的配置位置以及配置多個xml:如果在web.xml中不寫任何參數(shù)配置信息,默認的路徑是"/WEB-INF/applicationContext.xml",在WEB-INF目錄下創(chuàng)建的xml文件的名稱必須是applicationContext.xml(在MyEclipse中把xml文件放置在src目錄下)。如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個context參數(shù)。
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/applicationContext-*.xml</param-value><!-- 采用的是通配符方式,查找WEB-INF/spring目錄下xml文件。如有多個xml文件,以“,”分隔。 --> </context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>3、Spring使用Log4jConfigListener配置Log4j日志
Spring使用Log4jConfigListener的好處:
4、Spring使用IntrospectorCleanupListener清理緩存
這個監(jiān)聽器的作用是在web應用關(guān)閉時刷新JDK的JavaBeans的Introspector緩存,以確保Web應用程序的類加載器以及其加載的類正確的釋放資源。
如果JavaBeans的Introspector已被用來分析應用程序類,系統(tǒng)級的Introspector緩存將持有這些類的一個硬引用。因此,這些類和Web應用程序的類加載器在Web應用程序關(guān)閉時將不會被垃圾收集器回收!而IntrospectorCleanupListener則會對其進行適當?shù)那謇?#xff0c;已使其能夠被垃圾收集器回收。
唯一能夠清理Introspector的方法是刷新整個Introspector緩存,沒有其他辦法來確切指定應用程序所引用的類。這將刪除所有其他應用程序在服務器的緩存的Introspector結(jié)果。
在使用Spring內(nèi)部的bean機制時,不需要使用此監(jiān)聽器,因為Spring自己的introspection results cache將會立即刷新被分析過的JavaBeans Introspector cache,而僅僅會在應用程序自己的ClassLoader里面持有一個cache。雖然Spring本身不產(chǎn)生泄漏,注意,即使在Spring框架的類本身駐留在一個“共同”類加載器(如系統(tǒng)的ClassLoader)的情況下,也仍然應該使用使用IntrospectorCleanupListener。在這種情況下,這個IntrospectorCleanupListener將會妥善清理Spring的introspection cache。
應用程序類,幾乎不需要直接使用JavaBeans Introspector,所以,通常都不是Introspector resource造成內(nèi)存泄露。相反,許多庫和框架,不清理Introspector,例如: Struts和Quartz。
需要注意的是一個簡單Introspector泄漏將會導致整個Web應用程序的類加載器不會被回收!這樣做的結(jié)果,將會是在web應用程序關(guān)閉時,該應用程序所有的靜態(tài)類資源(比如:單實例對象)都沒有得到釋放。而導致內(nèi)存泄露的根本原因其實并不是這些未被回收的類!
注意:IntrospectorCleanupListener應該注冊為web.xml中的第一個Listener,在任何其他Listener之前注冊,比如在Spring's ContextLoaderListener注冊之前,才能確保IntrospectorCleanupListener在Web應用的生命周期適當時機生效。
<!-- memory clean --> <listener><listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener>?原文鏈接:http://tianweili.github.io/blog/2015/01/27/java-listener/
轉(zhuǎn)載于:https://www.cnblogs.com/hellojava/archive/2012/12/26/2833840.html
總結(jié)
以上是生活随笔為你收集整理的Listener 监听器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 少年派
- 下一篇: Sql结果导出为excel文件