servlet容器中listener、filter、interceptor的启动顺序

通过一个示例来说明启动顺序:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>testWeb</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.test.common.listener.CustomListener</listener-class>
    </listener>
    <filter>
        <filter-name>customFilter</filter-name>
        <filter-class>com.test.common.filter.CustomFilter</filter-class>
    </filter>
    <servlet>
        <servlet-name>customSerlet</servlet-name>
        <servlet-class>com.test.common.servlet.CustomServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>customSerlet</servlet-name>
        <url-pattern>/hello/</url-pattern>
    </servlet-mapping>
    <!-- springmvc 前端控制器 -->
    <servlet>
        <servlet-name>dispatcherSerlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherSerlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

自定义的listener:

package com.test.common.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.web.context.support.WebApplicationContextUtils;

import com.test.moudules.test.service.MyService;

public class CustomListener implements ServletContextListener {

    MyService myService;

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }

//servlet容器启动时执行的方法
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("*****listener  started*******");
        myService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())
                .getBean(MyService.class);
        myService.test();
    }

}

自定义的filter:

package com.test.common.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;

public class CustomFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("*****filter started*******");    
    }

}

自定义servlet:

package com.test.common.servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CustomServlet implements Servlet {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("*****servlet started*******");        
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        // TODO Auto-generated method stub
        
    }

}

控制台打印内容为:

*****listener  started*******

*****filter started*******

*****servlet started*******

从打印结果看执行顺序为listener——filter——servlet。

我们知道listener的contextInitialized方法是servlet容器启动时的触发回调所以可以得出一下结论:

容器首先启动,ServletContext先初始化,再执行listener,再执行filter,再执行servlet。

上一篇:java-如何使用注释链接自定义拦截器


下一篇:MyBatis的plugins解析