Listener,Filter,Servlet执行顺序和生命周期

Listener、Filter、Servlet定义:

Listener:

首先定义一个Listener,实现以下接口:

HttpSessionListener(用来监控session的创建,销毁等)

ServletRequestListener(用于监控servlet上下文request)

ServletRequestAttributeListener(用于监控request中的attribute的操作)

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestListener implements HttpSessionListener, ServletRequestListener, ServletRequestAttributeListener
{

    private Logger logger = LoggerFactory.getLogger(TestListener.class);


    public void sessionCreated(HttpSessionEvent arg0)
    {
        logger.info(".......TestListener sessionCreated().......");
    }


    public void sessionDestroyed(HttpSessionEvent arg0)
    {
        logger.info(".......TestListener sessionDestroyed().......");
    }

    public void requestInitialized(ServletRequestEvent arg0)
    {
        logger.info("......TestListener requestInitialized()......");
    }


    public void requestDestroyed(ServletRequestEvent arg0)
    {
        logger.info("......TestListener requestDestroyed()......");
    }

    public void attributeAdded(ServletRequestAttributeEvent srae)
    {
        logger.info("......TestListener attributeAdded()......");
    }


    public void attributeRemoved(ServletRequestAttributeEvent srae)
    {
        logger.info("......TestListener attributeRemoved()......");
    }


    public void attributeReplaced(ServletRequestAttributeEvent srae)
    {
        logger.info("......TestListener attributeReplaced()......");
    }
}

Filter:

package com.xy.web.filter;
 
import java.io.IOException;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class TestFilter implements Filter {
	private Logger logger = LoggerFactory.getLogger(TestFilter.class);
 
	public void destroy() {
		logger.info("..............execute TestFilter destory()..............");
	}
 
	public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {
		logger.info("..............execute TestFilter doFilter()..............");
		arg2.doFilter(arg0, arg1);
	}
 
	public void init(FilterConfig arg0) throws ServletException {
		logger.info("..............execute TestFilter  init()..............");
	}
}

Servlet:

package com.xy.web.servlet;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class TestServlet extends HttpServlet {
 
	private Logger logger = LoggerFactory.getLogger(TestServlet.class);
 
	/**
	 * 
	 */
	private static final long serialVersionUID = -4263672728918819141L;
 
	@Override
	public void init() throws ServletException {
		logger.info("...TestServlet init() init..........");
		super.init();
	}
	
	@Override
	public void destroy() {
		logger.info("...TestServlet init() destory..........");
		super.destroy();
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		logger.info("...TestServlet doPost() start..........");
		//操作attribute
		request.setAttribute("a", "a");
		request.setAttribute("a", "b");
		request.getAttribute("a");
		request.removeAttribute("a");
		//操作session
		request.getSession().setAttribute("a", "a");
		request.getSession().getAttribute("a");
		request.getSession().invalidate();
		logger.info("...TestServlet doPost() end..........");
	}
}

配置XML:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 测试filter -->
    <filter>
        <filter-name>TestFilter</filter-name>
        <filter-class>TestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>TestFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    <!-- 测试servlet -->
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <!-- 测试listener -->
    <listener>
        <listener-class>TestListener</listener-class>
    </listener>


</web-app>

配置好以后启动项目。

加载顺序:

日志:

查看启动日志如下:

信息: 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/rest/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-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()..............

********************************************

结论:
从启动,结束和运行时候的日志看:

  1. Listener生命周期:一直从程序启动到程序停止运行。
  2. ServletRequestListener:每次访问一个Request资源前,都会执行requestInitialized()方法,方法访问完毕,都会执行requestDestroyed()方法。
  3. HttpSessionListener:每次调用request.getSession(),都会执行sessionCreated()方法,执行session.invalidate()方法,都会执行sessionDestroyed()方法。
  4. ServletRequestAttributeListener:每次调用request.setAttribute()都会执行attributeAdded()方法,如果set的key在request里面存在,就会执行attributeReplacerd()方法,调用request.removeAttribute()方法,都会执行attributeRemoved()方法。
  5. Filter生命周期:程序启动调用Filter的init()方法(永远只调用一次,具体看启动日志),程序停止调用Filter的destroy()方法(永远只调用一次,具体看关闭日志),doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用,不管第几次,都在调用doGet(),doPost()方法之前)。
  6. Servlet生命周期:程序第一次访问,会调用servlet的init()方法初始化(只执行一次,具体看日志),每次程序执行都会根据请求调用doGet()或者doPost()方法,程序停止调用destory()方法(具体看结束日志)。
D:\software\apache-tomcat-6.0.43\bin\catalina.bat run
[2018-11-06 08:38:39,816] Artifact web_demo:war exploded: Waiting for server connection to start artifact deployment...
Using CATALINA_BASE:   "C:\Users\liu321\.IntelliJIdea2018.1\system\tomcat\Unnamed_web_demo"
Using CATALINA_HOME:   "D:\software\apache-tomcat-6.0.43"
Using CATALINA_TMPDIR: "D:\software\apache-tomcat-6.0.43\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.8.0_45"
Using CLASSPATH:       "D:\software\apache-tomcat-6.0.43\bin\bootstrap.jar"
Connected to the target VM, address: '127.0.0.1:49639', transport: 'socket'
十一月 06, 2018 8:38:41 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_45\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\WinSCP\;D:\software\ultraedit;C:\Program Files\IDM Computer Solutions\UltraCompare;C:\Program Files (x86)\OpenVPN\bin;D:\software\git\Git\cmd;.
十一月 06, 2018 8:38:41 下午 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
十一月 06, 2018 8:38:41 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 655 ms
十一月 06, 2018 8:38:41 下午 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
十一月 06, 2018 8:38:41 下午 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.43
十一月 06, 2018 8:38:41 下午 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
十一月 06, 2018 8:38:41 下午 org.apache.jk.common.ChannelSocket init
信息: JK: ajp13 listening on /0.0.0.0:8009
十一月 06, 2018 8:38:41 下午 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=0/32  config=null
十一月 06, 2018 8:38:41 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 174 ms
Connected to server
[2018-11-06 08:38:42,058] Artifact web_demo:war exploded: Artifact is being deployed, please wait...
..............execute TestFilter  init()..............
[2018-11-06 08:38:43,028] Artifact web_demo:war exploded: Artifact is deployed successfully
[2018-11-06 08:38:43,028] Artifact web_demo:war exploded: Deploy took 970 milliseconds
十一月 06, 2018 8:38:51 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory manager
......TestListener requestInitialized()......
...TestServlet init() init..........
..............execute TestFilter doFilter()..............
...TestServlet doPost() start..........
......TestListener attributeAdded()......
......TestListener attributeReplaced()......
......TestListener attributeRemoved()......
.......TestListener sessionCreated().......
.......TestListener sessionDestroyed().......
...TestServlet doPost() end..........
......TestListener requestDestroyed()......
D:\software\apache-tomcat-6.0.43\bin\catalina.bat stop
Disconnected from the target VM, address: '127.0.0.1:49639', transport: 'socket'
Using CATALINA_BASE:   "C:\Users\liu321\.IntelliJIdea2018.1\system\tomcat\Unnamed_web_demo"
Using CATALINA_HOME:   "D:\software\apache-tomcat-6.0.43"
Using CATALINA_TMPDIR: "D:\software\apache-tomcat-6.0.43\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.8.0_45"
Using CLASSPATH:       "D:\software\apache-tomcat-6.0.43\bin\bootstrap.jar"
十一月 06, 2018 8:39:14 下午 org.apache.coyote.http11.Http11Protocol pause
信息: Pausing Coyote HTTP/1.1 on http-8080
...TestServlet init() destory..........
..............execute TestFilter destory()..............
十一月 06, 2018 8:39:15 下午 org.apache.catalina.core.StandardService stop
信息: Stopping service Catalina
十一月 06, 2018 8:39:15 下午 org.apache.coyote.http11.Http11Protocol destroy
信息: Stopping Coyote HTTP/1.1 on http-8080
Disconnected from server

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值