Listener、Filter、Servlet定义:
Listener:
首先定义一个Listener,实现以下接口:
HttpSessionListener(用来监控session的创建,销毁等)
ServletRequestListener(用于监控servlet上下文request)
ServletRequestAttributeListener(用于监控request中的attribute的操作)
加载顺序:
日志:
查看启动日志如下:
信息: Initializing Coyote HTTP/1.1 on http-80
............
2016-1-14 0:47:04 org.apache.catalina.core.ApplicationContext log 信息: ContextListener: contextInitialized() 2016-1-14 0:47:04 org.apache.catalina.core.ApplicationContext log 信息: SessionListener: contextInitialized()
...........
2016-01-14 00:47:23,369 INFO TestFilter:28 - ..............execute TestFilter init().............. 2016-1-14 0:47:23 org.apache.catalina.core.ApplicationContext log 信息: Initializing Spring FrameworkServlet 'spring'
...........
2016-1-14 0:47:25 org.apache.catalina.startup.Catalina start 信息: Server startup in 21565 ms
*******************************************************************************
结论:
从启动日志来看,
启动的顺序为listener->Filter->servlet.
简单记为:理(Listener)发(Filter)师(servlet).
执行的顺序不会因为三个标签在配置文件中的先后顺序而改变。
生命周期:
日志:
访问项目路径:http://localhost/MyWebProject/common/test.do,访问action两次,打断点后查看日志情况:
第一次访问:
2016-01-14 00:03:03,991 INFO TestListener:26 - ......TestListener requestInitialized()...... 2016-01-14 00:03:04,001 INFO TestServlet:24 - ...TestServlet init() init.......... 2016-01-14 00:03:04,011 INFO TestFilter:23 - ..............execute TestFilter doFilter().............. 2016-01-14 00:03:15,275 INFO TestServlet:42 - ...TestServlet doPost() start.......... 2016-01-14 00:03:16,255 INFO TestListener:36 - ......TestListener attributeAdded()...... 2016-01-14 00:03:16,853 INFO TestListener:44 - ......TestListener attributeReplaced()...... 2016-01-14 00:03:18,561 INFO TestListener:40 - ......TestListener attributeRemoved()...... 2016-01-14 00:03:20,065 INFO TestListener:16 - .......TestListener sessionCreated()....... 2016-01-14 00:03:22,908 INFO TestListener:20 - .......TestListener sessionDestroyed()....... 2016-01-14 00:03:25,624 INFO TestServlet:52 - ...TestServlet doPost() end.......... 2016-01-14 00:03:27,746 INFO TestListener:30 - ......TestListener requestDestroyed()......
第二次访问:
2016-01-14 00:04:08,908 INFO TestListener:26 - ......TestListener requestInitialized()...... 2016-01-14 00:04:08,909 INFO TestFilter:23 - ..............execute TestFilter doFilter().............. 2016-01-14 00:04:14,385 INFO TestServlet:42 - ...TestServlet doPost() start.......... 2016-01-14 00:04:14,778 INFO TestListener:36 - ......TestListener attributeAdded()...... 2016-01-14 00:04:14,974 INFO TestListener:44 - ......TestListener attributeReplaced()...... 2016-01-14 00:04:15,342 INFO TestListener:40 - ......TestListener attributeRemoved()...... 2016-01-14 00:04:15,904 INFO TestListener:16 - .......TestListener sessionCreated()....... 2016-01-14 00:04:17,354 INFO TestListener:20 - .......TestListener sessionDestroyed()....... 2016-01-14 00:04:17,815 INFO TestServlet:52 - ...TestServlet doPost() end.......... 2016-01-14 00:04:19,044 INFO TestListener:30 - ......TestListener requestDestroyed()......
关闭项目,打印日志如下:
2016-1-14 0:40:15 org.apache.coyote.http11.Http11Protocol pause 信息: Pausing Coyote HTTP/1.1 on http-80 2016-1-14 0:40:16 org.apache.catalina.core.StandardService stop 信息: Stopping service Catalina 2016-1-14 0:40:16 org.apache.catalina.core.ApplicationContext log 信息: SessionListener: contextDestroyed() 2016-1-14 0:40:16 org.apache.catalina.core.ApplicationContext log 信息: ContextListener: contextDestroyed() 2016-01-14 00:40:16,561 INFO TestServlet:30 - ...TestServlet init() destory.......... ....... 2016-01-14 00:40:22,091 INFO TestFilter:19 - ..............execute TestFilter destroy()..............
********************************************
结论:
从启动,结束和运行时候的日志看:
Listener生命周期:一直从程序启动到程序停止运行。
ServletRequestListener:每次访问一个Request资源前,都会执行requestInitialized()方法,方法访问完毕,都会执行requestDestroyed()方法。
HttpSessionListener:每次调用request.getSession(),都会执行sessionCreated()方法,执行session.invalidate()方法,都会执行sessionDestroyed()方法。
ServletRequestAttributeListener:每次调用request.setAttribute()都会执行attributeAdded()方法,如果set的key在request里面存在,就会执行attributeReplacerd()方法,调用request.removeAttribute()方法,都会执行attributeRemoved()方法。
Filter生命周期:程序启动调用Filter的init()方法(永远只调用一次,具体看启动日志),程序停止调用Filter的destroy()方法(永远只调用一次,具体看关闭日志),doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用,不管第几次,都在调用doGet(),doPost()方法之前)。
Servlet生命周期:程序第一次访问,会调用servlet的init()方法初始化(只执行一次,具体看日志),每次程序执行都会根据请求调用doGet()或者doPost()方法,程序停止调用destory()方法(具体看结束日志)。
********************************************