需要了解两个概念:
1、ServletContext :是web项目的上下文,可以理解为整个Web应用的全局变量,项目中所有的方法可以获取ServletContext。
2、ApplicationContext:是spring的BeanFactory的实现类,把spring所有配置加载进去,所依赖的bean创建实例,默认参数等等初始化。
springmvc web项目,web容器启动会主动加载web.xml文件,以下贴出web.xml文件内容。
以Tomcat举例,启动Tomcat之后,首先会加载web.xml文件:
a)容器首先读取web.xml中的<context-param>的配置内容和<listener>标签中配置项;
b)紧接着实例化ServletContext对象,并将<context-param>配置的内容转化为键值传递给ServletContext;
c)创建<listener>配置的监听器的类实例,并且启动监听;
d)随后调用listener的contextInitialized(ServletContextEvent args)方法,ServletContext = ServletContextEvent.getServletContext(); 此时你可以通过ServletContext获取context-param配置的内容并可以加以修改,此时Tomcat还没完全启动完成。
e)后续加载配置的各类filter;
f)最后加载servlet;
最后的结论是:web.xml中配置项的加载顺序是context-param=>listener=>filter=>servlet,配置项的顺序并不会改变加载顺序,但是同类型的配置项会应该加载顺序,servlet中也可以通过load-on-startup来指定加载顺序。
通过以下web.xml的配置我们可以看到,初始化加载context-param时,我们可以把配置参数或者配置文件加载到全局ServletContext(键值对形式)中。之后加载所有配置的监听器,并启动监听器的实例。在监听器创建实例完成后,会加载ServletContext中的配置,如果是配置文件则会读取文件,实现配置文件的功能(如注解扫描,bean注入,数据源配置等),如:配置文件中指定注解扫描的范围,在代码controller中添加@controller的注解,从而dispatcherServlet可以实现调用分发的功能。也可以配置一些其他的注入或者驱动。 之后会去加载过滤器,实现过滤器的功能,最后加载servet配置,做对应的配置处理。启动顺序(http请求顺序):监听器 > 过滤器 > 拦截器(context-param-->listener-->filter-->servlet-->interceptor)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>listener.SessionListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>web.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
学海无涯苦作舟