[课本划重点]SpringMVC

写个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);

				//获取当前请求对应的handler
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// 确定当前handler对应的handler适配器
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				//…………

				try {
					// 调用handler(controller)获取返回的ModelAndView
					mv = 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 afterCompletion
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				return;
			}
			// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}


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




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值