我们在使用Spring+SpringMVC开发项目中,web.xml中一般的配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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" version="3.0"> 3 ????<!-- 加载spring配置 ?4 ????????默认查找的配置文件位置是:WEB-INF/applicationContext.xml。 5 ????????可通过下面参数指定文件位置--> 6 ????<context-param> ??7 ????????<param-name>contextConfigLocation</param-name> ??8 ????????<param-value> ??9 ????????????classpath:applicationContext.xml10 ????????</param-value>11 ????</context-param>12 ????13 ????<filter>14 ????????<filter-name>CorsFilter</filter-name>15 ????????<filter-class>com.filter.CORSFilter</filter-class>16 ??????</filter>17 ??????<filter-mapping>18 ????????<filter-name>CorsFilter</filter-name>19 ????????<url-pattern>/*</url-pattern>20 ??????</filter-mapping>21 ??????22 ????<listener> ?23 ????????<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> ?24 ????</listener>25 ????26 ??<servlet>27 ????<servlet-name>spring-mvc</servlet-name>28 ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>29 ??????<!-- spring mvc 默认加载的配置文件为/WEB-INF/[servlet-name]-servlet.xml,也可通过以下参数指定 -->30 ????<!-- <init-param>31 ????????<param-name>contextConfigLocation</param-name>32 ????????<param-value>/WEB-INF/spring-mvc-servlet.xml</param-value>33 ????</init-param> -->34 ????<!-- load-on-startup设置为1,表示项目启动时加载 -->35 ????<load-on-startup>1</load-on-startup>36 ??</servlet>37 </web-app>
那么Listener中的contextInitialized方法是什么时候被调用呢?答案就在org.apache.catalina.core.StandardContext类的startInternal方法中
1 //org.apache.catalina.core.StandardContext 2 ?@Override 3 protected synchronized void startInternal() throws LifecycleException { 4 ????//省略部分代码,只列出关键代码 5 // Configure and call application event listeners 6 ????????????if (ok) { 7 ????????????????if (!listenerStart()) { 8 ????????????????????log.error(sm.getString("standardContext.listenerFail")); 9 ????????????????????ok = false;10 ????????????????}11 ????????????}12 13 ????????????try {14 ????????????????// Start manager15 ????????????????Manager manager = getManagerInternal();16 ????????????????if ((manager != null) && (manager instanceof Lifecycle)) {17 ????????????????????((Lifecycle) getManager()).start();18 ????????????????}19 ????????????} catch(Exception e) {20 ????????????????log.error(sm.getString("standardContext.managerFail"), e);21 ????????????????ok = false;22 ????????????}23 24 ????????????// Configure and call application filters25 ????????????if (ok) {26 ????????????????if (!filterStart()) {27 ????????????????????log.error(sm.getString("standardContext.filterFail"));28 ????????????????????ok = false;29 ????????????????}30 ????????????}31 32 ????????????// Load and initialize all "load on startup" servlets33 ????????????if (ok) {34 ????????????????if (!loadOnStartup(findChildren())){35 ????????????????????log.error(sm.getString("standardContext.servletFail"));36 ????????????????????ok = false;37 ????????????????}38 ????????????}
第7行执行触发listener事件,listenerStart()方法中有listener.contextInitialized(event)语句,直接调用listener的contextInitialized方法。
第27行会执行了filter的init方法,具体细节请参照tomcat源码,在此不在详细赘述。
第34行,如果在web.xml中servlet标签指定了<load-on-startup>1</load-on-startup>(值大于0即可),会执行servlet的实例化,然后调用servlet的int(ServletConfig config)。
由此也可指定在Tomcat启动时,这三者调用的先后顺序为listener-->filter-->servlet。
注:StandardContext类的startInternal方法会在Tomcat启动时调用。
Web开发中Listener、Filter、Servlet的初始化及调用
原文地址:https://www.cnblogs.com/jintian315/p/8628873.html