Spring MVC与Web环境(四):SpringMVC对HTTP请求的分发处理

这一段时间一直在看关于算法部分的书籍,所以始终没来的及更新自己的博客。之前就已经看完了Spring MVC的全部文章,今天就更新完我的关于Spring源码学习的最后一篇文章。

1.大体流程

上次说到了关于handler(也就是Controller层对象的获取),那么服务器是根据用户请求的url来进行确认访问某一个HandlerMapping取出其中的handler对象以及相应的拦截器链,但是这个请求的分发处理,之前的内容并没有提及。从书上可以了解到是通过DispatcherServlet的doService方法进行实现的。

doDispatch(request, response);

这个方法中的doDispatch是分发请求的入口。

HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;

这两个对象一个表示发送的请求,一个表示拦截器链,这个拦截器链和之后和handler绑定到一起的拦截器链是有关系的。

mappedHandler = getHandler(processedRequest);

然后引入了一个我们很熟悉的对象,ModelAndView对象,将有这个对象来持有handler处理请求的结果。

	ModelAndView mv = null;

在实际调用handler的时候,要使用HandlerAdapter检查一下handler的合法性,生成一个HandlerAdapter的对象ha

通过调用HandlerAdapter的handle方法,实际上触发对Controller的handleRequest方法的调用。通俗一点,就是我们在声明的RequestMapping的方法下写的那些代码的执行。将处理的结果保存在ModelAndView对象中

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

然后调用render()方法将mv对象进行展现。从中我们大致了解了整个的流程。

现在我们来具体的讲解一下里面的一些细节

2.handler对象的获取

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			if (logger.isTraceEnabled()) {
				logger.trace(
						"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
			}
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
		return null;
	}

原理和之前的博客写的比较类似,也是从注册完成的handlerMappings中查到的。

还有关于getHandlerAdapter()方法

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

这个也是为了保证handler对象要是Controller接口的实现。

3.Spring MVC视图的呈现

这个视图的呈现交给了render方法进行处理

首先对传入的ModelAndView对象进行解析并获取的视图对象

View view;
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);

在view对象配置完毕后,调用view对象的render方法,这个方法是由它的子类AbstractView进行实现的,从书上的描述中我们不难发现例如jsp页面的具体渲染是由我们配置的服务器来完成的。View对象只是包含了jsp的名字以及需要显示的一些数据,就像我们用jstl表示的数据一样。这些数据保存在model中。

4.总结

关于Spring源码的学习,对于我目前的学习水平而言就要告一段落了。Spring的扩展功能很多,也绝对不只是我看到的书上的这些,通过对于Spring的依赖注入,AOP,事务处理以及Spring MVC的学习。我可以清楚地感觉到,这个框架所体现出的依赖注入以及控制反转思想,我们将我们需要的bean写在xml中。由Spring生成一个生命周期为服务器运行周期内的一个ApplicationContext容器进行统一的管理。增强了我们代码的解耦性,在生成对象的时候我们才会真正为决定这个对象所依赖的其他对象,这使得对象的声明看其来更加明了。我们不需要为一个具有多种嵌套依赖可能性的类声明多次,只需要声明一个最原始的模板,将它所依赖的对象由接口表示。在真正调用的时候通过依赖注入的方式进行实例化,这使得我们的代码更加灵活。

通过对Spring源码的阅读,原本神秘的Spring其实和我们日常写的代码是相同的,只是整个框架对于健壮性以及高并发等要点进行了充分的完善。源码的解析并不神秘,当然只是看一遍这本书,其中的很多细节都没有展示出来,我只是了解了大概的流程。但是这本书对我的帮助是巨大的,这也体现了面向接口的编程思想,每一层只对它的上层负责,它所需要的功能实现则由它的下一级接口进行统一的实现。

单纯地对这本书进行查看还不足以完全地了解Spring,如果你有兴趣,可以试着自己手写一下关于Spring的整个实现过程。当然有书籍进行帮助,书名为《Spring专业开发指南》,有兴趣者可以进行查看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值