一:请求的分发过程
1. 请求的接管
<!-- 前端控制器的配置 -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定spring配置文件的位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 所有以.html和.json的请求都由dispatcherServlet来处理的配置 -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
在web.xml 中配置上面的 servlet 则 所有的 htm 和 json 请求都将由
org.springframework.web.servlet.DispatcherServlet
这个类来处理。
这个类就是一个 servlet. 他的 doService 方法调用 doDispatch 方法。这个方法的大致过程是:
1. mappedHandler = getHandler(processedRequest, false);
依据请求参数获得 对应的映射处理器
2. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
调用具体的处理方法:
将请求,相应,和处理器对象传递给 handle 方法。
该方法返回 org.springframework.web.servlet.ModelAndView
3. 请求处理完毕之后 返回数据
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
二:DispatcherServlet 的初始化
对于DispatcherServlet 类要想能够正确的分发请求和返回请求,则其必须拥有 映射处理的map 和模型视图的map ,
映射处理的map 通过下面的方法获得:
mappedHandler = getHandler(processedRequest, false);
模型视图的map的map(视图分解器)
this.viewResolvers
在 initViewResolvers 方法中初始话。
initStrategies 中初始话这些东西,而这个方法最终被 DispatcherServlet 的 父类:
org.springframework.web.servlet.HttpServletBean
的init方法所调用。所以 映射处理器是在 servelt 被初始话时调用。
三: DispatcherServlet 对象是何时被创建的
DispatcherServlet其实就是一个 Servlet ,那么对于一个 Servlet 他是何时被创建的。
1. web客户向Servlet容器发出HTTP请求;
2. Servlet容器解析web的HTTP请求.
3. Servlet容器创建一个HttpRequest对象,在这个对象中封装了http请求信息;
4. Servlet容器创建一个HttpResponse对象;
5. Servlet容器(如果访问的该servlet不是在服务器启动时创建的,则先创建servlet实例并调用init()方法初始化对象)调用HttpServlet的service()方法,把HttpRequest和HttpResponse对象为service方法的参数传给HttpServlet对象;
6. HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
7. HttpServlet调用HttpResponse的有关方法,生成响应数据;
8. Servlet容器把HttpServlet的响应结果传给web客户.
上面是 Servlet 处理请求的过程。 Servlet 在 第 5 步中被初始话。但是如果在web.xml中配置 DispatcherServlet 时加上下面的属性:
<load-on-startup>1</load-on-startup>
则这个,Servlet 将在 Servlet容器(tomcat)初始化的时候也被初始化,就会调用起 init 方法。这样在 tomcat 启动时,DispatcherServlet类所需要的资源就被初始化好了,例如:请求映射处理器Map,和视图分解器Map。
初始化,这些东西时,需要的配置文件也在 DispatcherServlet 的Servlet配置中申明:
<!-- 加载springMVC的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</init-param>
这个配置文件applicationContext-mvc.xml:中的配置信息,
1. 请求映射处理器。
<!-- 自动扫描的包名 -->
<context:component-scan base-package="com.shishuo.cms"></context:component-scan>
通过注解分析 获得 com.shishuo.cms 下面所有类和包中的类的映射处理器。
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
<property name="cache" value="false" />
<property name="prefix" value="/" />
<property name="suffix" value=".ftl" /><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑 -->
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
上面是 freemarker 的视图分解器配置。
</bean>