下面的说明都是对于这图的描述:
如图所示:spring的mvc分两个阶段来说,调用-one和调用-two
1:HttpServlet的初始化阶段(init方法) servlet的init方法解析,在spring中这个方法在HttpServletBean (抽象类)中所以得从这个抽象类中的init方法开始如上图所示。
这一步主要做的动作主要是为了为每一个servlet创建一个WebApplicationContext对象,通过FrameworkServlet类中的initServletBean()方法。
首先来看HttpServletBean类的init方法,再看子类FrameworkServlet中initServletBean()方法
接着 调用initWebApplicationContext()方法是为了把servlet的ServletContext和ServletConfig设置到web应用上下文,下面解释下这两个对象:
ServletConfig:代表当前Servlet在web.xml中的配置信息
String getServletName() -- 获取当前Servlet在web.xml中配置的名字
String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
Enumeration getInitParameterNames() -- 获取当前Servlet所有初始化参数的名字组成的枚举
ServletContext getServletContext() -- 获取代表当前web应用的ServletContext对象
在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,
并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
ServletContext:代表当前web应用(非常重要)
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,
可以通过ServletConfig.getServletContext方法获得ServletContext对象。
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,
因此Servlet对象之间可以通过ServletContext对象来实现通讯。
ServletContext对象通常也被称之为context域对象。
从上面的描述就知道WebApplicationContext拥有了ServletContext和ServletConfig的功能。
这里还要说下ServletContext对象是存放在ConcurrentHashMap中也就是说WebApplicationContext对象中的ServletContex值是从ConcurrentHashMap中获取出来的
上面的动作做完之后,再将上下文发布为servlet上下文属性 ,这样就可以在想要用的地方通过WebApplicationContext获取想要的数据:
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);到这里调用-one的这一条线就完了。
2:用户请求servlet的doGet方法和doPost方法,但是在spring中它做了封装,帮我们封装到FrameworkServlet(抽象类)中,所以首先先从这个类中的这两个方法入手。
由于这两个方法调用了同一个方法processRequest(request, response);
由于doService方法的实现是在子类中,所以我们调用的时候实际是执行到了DispatcherServlet类的doService方法
接下来我们来看doDispatch方法:
下面我们就进入到handle方法里面,因为这里调用了AbstractHandlerMethodAdapter中的handle方法,而handle又调用了RequestMappingHandlerAdapter类中的handleInternal方法,:
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
handleInternal方法调用了invokeHandlerMethod,invokeHandlerMethod又调用了ServletInvocableHandlerMethod类的invokeAndHandle方法,invokeAndHandle调用了InvocableHandlerMethod类的invokeForRequest方法:
方法调用到这个,我们又得回到DispatcherServlet类中的doDispatch方法中,因为方法调用执行完了,还得把方法执行的参数返回显示到视图VIEW上,接下来看doDispatch中的后半段
总结: 经过上面的流程我们知道DispatcherServlet类相当于一个mvc的总控之类,所有请求都需要经过它,通过HandlerAdapter适配器类调用对应的handle,也就是说执行对应的控制器中的方法并生成一个ModelAndView对象,然后再通过ModelAndView对应解析视图数据,返回出去。