一 、在web项目启动的时候会加载web.xml,它的节点有哪些呢?
1.<context-param>:应用范围内上下文初始化参数
<context-param>
<param-name>param<param-name>
<param-value>value</param-value>
</context-param>
2.<listener>:监听器类
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3.<filter>:过滤器
<filter>
<filter-name>CharacterEncodingFilter</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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.<servlet>
//配置Spring MVC,指定处理请求的Servlet,有两种方式:
//1. 默认查找MVC配置文件的地址是:/WEB-INF/${servletName}-servlet.xml
//2. 可以通过配置修改MVC配置文件的位置,需要在配置DispatcherServlet时指定MVC配置文件的位置。
//这里使用的是第二种方式
<!-- Springmvc的核心控制器 -->
<servlet>
<servlet-name>dispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatchServlet</servlet-name>
<url-pattern>*.shtml</url-pattern>
</servlet-mapping>
web.xml加载顺序为:context-param<listener<filter<servlet
问题1:改换context-param,listener,filter,servlet配置语句在web.xml中的顺序,其启动顺序是否会变呢?
答案是否定的,即便是吧关于servlet的配置放在最前面,其加载顺序还是会在最后。但是需要注意的是,在同一类型的配置项中,其在web.xml的顺序会影响其启动的顺序,比如有两个filter,filter1在配置文件中先于filter2,则filter1先于filter2被加载实例化。
问题2:org.springframework.web.context.ContextLoaderListener的作用。
ContextLoaderListener这个监听器继承自ContextLoader并且实现了ServletContextListener,他的主要作用是去寻找并读取spring主配置文件ApplicationContext.xml(也就是context-param中所定义的contextConfigLocation),然后启动WebApplicationContext,也可叫做web应用上下文,并且最重要的是,它将WebApplicationContext注入到servletContext容器中(作为servletContext的一个attribute,属性),并且在WebApplicationContext中保留了一个servletContext的引用。所以我们可以通过
WebApplicationContext得到servletContext,也可以通过servletContext获取到WebApplicationContext。
通过WebApplicationContext得到servletContext:
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
ServletContext servletContext = webApplicationContext.getServletContext();
通过servletContext获取WebApplicationContext:
ServletContext servletContext = event.getServletContext();
ApplicationContext application = WebApplicationContextUtils .getWebApplicationContext(servletContext);
问题3:webApplicationContext和servletContext是谁先存在呢?
当然是servletcontext,ServletContext是web容器(tomcat等)为web项目提供的一个全局上下文,一个web项目中只有一个。它其实是后面生成的WebApplicationContext容器的一个宿主。
所以:简单来说:web项目启动经过如下步骤。(个人观点,有错误指正)
1.项目启动,加载依赖的jar包。
2.web容器(tomcat)先读取web.xml的节点context-param、listener
3.web容器创建ServletContext,容器将context-param的值以键值对形式给servletcontext,并且运行ContextLoaderListener监听器,该监听器因为实现了ServletContextListener接口,所以当发现容器生成了一个ServletContext实例的时候,便会执行ServletContextListener接口的初始化方法,在该初始化方法中根据contextConfigLocation指定的位置去读取spring的主要配置文件,然后生成web应用上下文WebApplicationContext,并且将其作为一个属性注入到ServletContext中。
4.初始化WebApplicationContext以后,启动了“业务层”的spring容器,并开始加载病初始化applicationContext配置文件中所扫描的类。
5.然后就是初始化filter,最后初始化servlet。
所以说作为web项目,WebApplicationContext的生成必须要在web容器存在的情况下才能实现,因为他需要ServletContext,而ServletContext是web容器生成的。
问题4:DispatcherServlet是什么?有什么用。
简单来说,它就是一个servlet,但是它是一个特殊的servlet,是整个spring mvc框架的核心,他是一个前端servlet,spring mvc经过前端servlet来接受所有的请求,然后再讲具体工作派发给其他的的servlet来具体实现。
同时,再servlet的配置文件中,我们看到名为SpringMvc的读取了contextConfigLocation所定义的配置文件(classpath:ApplicationContext-mvc.xml),启动了web层的spring容器,在这个容器里,我们初始化了所有的controller类。如控制台打印的日志所示。
问题5:由于初始化DispatcherServlet伴随着启动spring mvc容器(即上面所说的web层容器),所以需要较长的时间,所以我们希望在项目启动的时候就进行初始化的操作。这也是我们将load-on-startup项设为1的原因。因为这个属性设为正数的表示在项目启动的时候就初始化,数字越小表明越早初始化。如果我们将其设为负数的话。那么在项目启动的时候,将不会启动spring mvc的容器,而是当我们第一次访问某个controller所对应的action的时候才来加载启动容器,这将会造成较长时间的等待,所以我们一般将load-on-startup设为1.
二、获取web.xml初始化值
对于<init-param>:获取servlet初始值
this.getInitParameter("")//this代表当前对象、getServletConfig.getInitParameter("")//getServletConfig()仅仅应用于当前servlet
对于<context-param>:获取application中的初始值
getServletContext.getInitParameter("")
参考资料:https://www.cnblogs.com/roy-blog/p/7656834.html
https://blog.csdn.net/qq_20805103/article/details/77851996
http://www.360doc.com/content/12/0417/15/1007797_204407987.shtml