[课本划重点]SpringMVC

来源:互联网 发布:魅动力知乎 编辑:程序博客网 时间:2024/04/29 19:30

写个springmvc的,毕竟面试经常问的。。。

出自《Spring源码深度解析》

-----------------------------------

♦️SpringMVC是基于Servlet功能实现的,通过实现Servlet接口的DispatcherServlet来封装核心功能实现。实现原理是通过DispatcherServlet拦截所有的URL来达到控制的目的。

配置文件部分

1.web.xml

contextConfigLocation:上下文配置地址,一般指向applicationContext.xml

DispatcherServlet:这个是一定要配置的,配置这个拦截所有的URL

contextLoaderListener

2.applicationContext.xml(名字怎么取随便你)

viewResolver:这个呢,不同的模版需要指定不同的类,用来处理ModelAndView返回的视图名,比如prefix,suffix

-----------------------------------

ContextLoaderListener

在web.xml中以<context-param>的方式注册并使用ContextLoaderListener。因为 ContextLoaderListener implements ServletLoaderListener ,所以我们可以在为客户端提供服务之前向ServletContext中添加任意的对象,且这个对象会在 ServletContext 启动时初始化,整个ServletContext运行期间都是可见的。

每个Web应用都有一个ServletContext,在应用启动时被创建,应用关闭时销毁,全局范围内有效。其核心逻辑就是初始化WebApplicationContext实例并存放在ServletContext中。

WebApplicationContext在配置中只能被声明一次.


DispatcherServlet

先回顾一下Servlet:这个在学生时代用于处理请求的类(准确的说,Servlet是一个接口,我们称实现这个接口的类为Servlet类)

生命周期:

第一次调用servlet对象时被初始化

接收请求时会为当前请求创建一个servletRequest和servletResponse,返回响应结果后销毁

当web应用终止时,servlet容器会调用destroy方法销毁servlet对象


先看一下DispatcherServlet类的主要依赖关系:


图(1-1)

图1-1可以看出,DispatcherServlet的重要初始化信息全在onRefresh(ApplicationContext context)中。哦,对了,图里方法的参数我忘了写进去了,懒得改了,凑合着看吧。

也就是说,初始化DispatcherServlet时,ApplicationContext已存在,即spring的IOC容器已经运行了。

所以在servlet的配置当中,<load-on-startup>param</load-on-startup>param需要配置成正数,一般为1。标记容器是否在启动的时候就加载这个servlet。当param值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。

------------------------------


图(1-2)

核心干货。。。认真阅读。。。一遍不行就两遍。。。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;//从handlerMapping中得到的                HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);//获取当前请求对应的handlermappedHandler = getHandler(processedRequest);if (mappedHandler == null || mappedHandler.getHandler() == null) {noHandlerFound(processedRequest, response);return;}// 确定当前handler对应的handler适配器HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//…………try {// 调用handler(controller)获取返回的ModelAndViewmv = ha.handle(processedRequest, response, mappedHandler.getHandler());}finally {if (asyncManager.isConcurrentHandlingStarted()) {return;}}applyDefaultViewName(request, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}                        //处理结果processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Error err) {triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionmappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);return;}// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}


------------------------------




0 0