通过一个示例来说明启动顺序:
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。