Spring MVC:原理与使用

本人上一篇博文提到了Spring的注入功能,这样在存在对象依赖(具体意思可见上一篇博文)的时候就不用自己生成一个对象了,特别是对于较多的无状态对象的时候,这个特别方便,加上Spring提供的用xml配置文件和代码注解两种方式,使得使用更加灵活。然而spring的功能远不止如此,Spring的强大功能其实还在于做Java后台框架,即Spring MVC,把后台的逻辑和和视图解耦分离,方便使用与扩展,特别是在大型项目中很有用。

PS:卖个自己的广告,上一篇博文《Spring注入:配置与注解》 (如果是在其他抄袭网站看到这篇博文的人可以通过这个网址找到上一篇博文在哪里,这样会有一个比较连贯的了解,顺便吐槽一下这些抄袭网站,自己爬取别人的博文放到自己的网站上,还不写个引用自哪里,这终究不太好吧~~~)http://blog.csdn.net/u011579138/article/details/51379066

MVC

首先大概介绍一下什么是MVC,由于自己也是渣渣,所以为方便初学者学习,还是介绍一下自己理解中的MVC(不一定是完全对的,仅作参考,老鸟可以直接跳过这一段)。MVC是三个东西的缩写,model、view、controller。

Model:业务模型类,例如:购物程序中一些包含用户信息的类,这些类只有get和set的方法来获取值,或者经常提到service,就是那些不需要具体值的对象,只是进行方法调用的那些类,这些都属于model。可以简单理解为处理业务逻辑的类

View:给用户看的视图,例如html页面,js,css效果这些。简单理解就是给用户看的东西

Controller:控制器,这样描述可能不太好理解,例如,浏览器来了一个请求,这时候控制器(controller)就用来分发给具体业务模型(model),业务模型处理完之后返回一个视图(view)给用户,这就是一个完整流程。有初学者可能会控制器控制什么,例如一个url,其中传了个参数1可能是请求一个网页,参数2可能是请求另一个网页,这时候控制器就是用来把这个请求到底是交给哪个业务处理模型。

就像快递,用户寄一个快递,控制器(controller)拿到快递,根据用户的请求(参数),交给对应地区的快递员(model),快递员处理完发送任务之后返回一个结果(view)给用户,告诉用户我搞定了。这就是一个mvc的流程。

Spring MVC 原理

其实是基于servlet的一个框架,servlet可以理解为网页跟逻辑的映射的(具体还是请自学一下),spring是把所有的请求全部映射到一个叫DispatcherServlet的一个对象去,然后由这个对象进行分发请求,有点类似于controller的感觉。DispatcherServlet找到一个handler(这里其实是通过在一个叫handlerMappings的List对象中来找handlerExecutionChain,在这个handlerExecutionChain里面有handler和Interceptor,源码详情如果后面本人有空会写一篇博客来讨论源码实现,由于过于复杂,这里就不介绍了太多)。找到handler之后,这时候会通过handler找到HandlerAdapter,这里的handler和handlerAdapter的区别,根据我查的几篇博客是这样说的:handler负责找到需要处理这个请求的类,adapter负责找到这个类中具体哪个方法处理这个请求(以下两篇博客都是这样说的,第二篇中举的例子已经过时,里面那个adapter已经被官方废弃了)。

http://www.360doc.com/content/14/1024/23/18637323_419613178.shtml

http://www.mamicode.com/info-detail-877142.html

这里本人却并不赞同这个说法,后面本人会解释一下,这里先继续介绍spring MVC的流程,dapater找到之后会调用handle方法来调用处理这个请求的函数(即model)。一般这个函数会返回一些东西,经过conver的处理生成一个界面(即view),view生成好了就会返回给用户,这样一个处理流程就结束了。如下图所示

Handler和HandlerAdapter真正的作用?

但是本人通过查看源码,发现并不是像这样,其实在handler的时候就已经确定了哪个具体的方法来处理这个请求。如下图,这里其实已经找到了对应的方法,downloadReportFile,所以这里并不是找到类,而且已经找到了类里面的方法了,而且这里的确定方法的标准其实就是判断url和http的方法(GET POST)。

其次,再看看adapter是怎么来的,是不是真的确定了具体的方法,先贴几张源码(这里不用慌,作为初学者担心看代码很烦或看不懂,慢慢静下心来,其实很容易看懂的,而且我会用详细的语言来表述,所以不要跳过这段)

这里可以看到通过getHandler得到了mappedHandler,其实mappedHandler是一个handlerExecutionChain(可以参考我上面那段提到的,如果文字太多可以用浏览器的ctrl+f找handlerExecutionChain那段)。找到之后检查handler和mappedHandler是不是空,然后通过handler获得HandlerAdapter。

再下一层,看看getHandlerAdapter的原理,从handlerAdapters这个容器中遍历,如果支持这个handler就返回相应的handlerAdapter(照顾初学者:logger是用来打log日志的工具,和代码逻辑无关)。

然后再下一层,看看spports里面是怎么实现的。可以看到就是判断了一下handler的类型,并且看supportsInternal的返回结果,很简单。

那么再下一层看看supportsInternal这个函数怎么实现,结果一看,就是返回true。所以你发现其实得到handlerAdapter其实和定位方法没有任何关系。

所以我才质疑handlerAdapter的作用究竟是什么。我有问过公司一个主管,结果发现他自己练spring本身的运行过程都不大清楚,所以也没有得到这个问题的答案。

这里的handlerAdapter有好3个,上面的源码是第一个的,但是后面两个我也看了,只是检查了一下是不是属于那些类型,也没有定位到具体的方法,也就是说handlerAdapter里面根本就没有用来指向哪个方法,指向具体的方法是在handler里面。

所以在这里个人猜测,handler是指向具体的方法,handlerAadpter是用来执行具体的方法的(在后面会看到,其实handlerAapter中有一个handler的方法,就是在这个方法中调用handler中指向的那个方法)

HandlerIntercetptor

这里顺便简单解释一下handlerIntercetptor的作用,这两个拦截器其实就是个事件触发机制,在handle这个请求前做一些事儿(HandlerExecutionChain中的applyPreHandle),在handle这个请求之后做些事儿(HandlerExecutionChain中的applyPostHandle),类似于Netty中的pipeline机制。也就是spring在让你处理请求前或请求后,你可以通过添加interceptor做一些处理。

HandlerExecutionChain

看名字顾名思义就是执行链,这里面包含了一个handlerInterceptor的容器,默认有两个interceptor,然后preHandle和postHandle都是空。如果自己要实现可以在里面自己添加自己的interceptor。然后这里面还包括了一个handler,上面已经说过了。

图中mappedHandler就是HandlerExecutionChain,先调用所有inteceptor的PreHandle,然后再调用adapter的handle函数,再调用所有interceptor的postHandle。其中如果applyPreHandle如果返回false,也就是事件处理完毕了,就是说不需要handler中那个函数去处理了,所以这个时候就会直接return,例如有些参数明显不合法,可以直接不作处理,如下图

Spring MVC 用法

了解完概念,再来介绍一下用法。这里的用法我只介绍用注解的方法,这种比较常用一些。Spring MVC中大部分的代码都已经写好了,自己需要做的就是需要写业务处理。

首先拦截请求,用注解注入一个类,在这个类中编写方法,用@RequestMapping注解,value就是uri,params就是参数,也可以再加个method,判断http的方法是GET还是POST,函数的体的参数和返回类型完全自己定义,没有特殊的格式。(一开始我总不清楚这些函数为什么要这么多参数,是不是固定要这些的,后来看了源码发现其实这些是用java反射做的,参数是不限制个数的那种函数申明方式,返回类型是object,所以这些返回类型和参数没有固定的)。不过一般可以定义自己需要的一些参数。

返回值的作用

没有@ResponesBody

没有这个注解,这注意返回的东西,是作为资源调用的标识使用,例如你返回一个a的string类型,会默认解析为找一个名字叫a的html或者js之类的资源文件。如果要返回其他类型,就得看看spring默认支不支持解析咯,有可能自己还要写解析的类,这个类就是ViewResolver,专门解析这些返回对象的(可以参见上面那个流程图中的第五步)。当然这里的资源都是静态的,如果需要一些动态的参数,这时候就要用到modelMap了(上面那个流程图也有,第六步),就是在ViewResolver处理之后再用到modelMap里面的一些值来动态处理。

有@ResponseBody

如果这个注解,就意味着返回的对象不是作为资源标识符来使用,而是作为http返回的包体内容。上面那种是属于你返回个东西,spring帮你解析成view了返回,这是把你返回的东西直接当做内容返回了。顾名思义ResponseBody。这里返回的内容也是需要解析,解析这个的叫converer,把返回的对象解析成可以放进http包体的内容。Spring默认支持了几种返回,例如string,json,还有byteArray(预知详情,自己可以试着看看源码)。所以如果你要返回一个你自己写的对象,那就要自己写个converer才行,不然最后没有返回的。

这就是大概的用法,其实Spring还有很多种用法,里面所支持的东西也还很多,例如可以和其他框架,像MyBatis或者Struts配合,但是本人能力有限,研究spring一周才勉强研究出这些东西,与其他框架配合也只做了一点与MyBatis相关的东西,以后若是有机会还是得多加练习才行。

另外ZZ再嘴多一点,照应开头所说的。其实Spring MVC也就是基于Servlet的,所以不用Spring MVC这种办法直接用Servlet也是可以实现网络请求处理的。而且spring通过大量调用判断其实是会牺牲掉一些性能的。但是依旧还是有人使用spring,其实就在于大型项目管理和维护比较比较方便一点这样逻辑会更清楚,因为这里将model,view,controller给分开了,处理逻辑和返回界面在不同的地方,如果用servlet势必会搅在一起。这大概就是spring的一个好处。但性能方面spring应该是处于劣势。

PS:本人是个渣渣,但是每次在研究完一个东西之后还是会总结一下这个框架有啥优势和不足,这样才是一个我这种渣渣提升的一个方向,所以万望诸君共勉。

因为前人,才能更高

Spring源码分析 http://www.360doc.com/content/14/1024/23/18637323_419613178.shtml

PS:本篇博客主要根据ZZ本人查看源码和参考这篇博文,其他博文也有参考,但参考程度不多,故这里就不列举出来,但也很感激前人留下的文献,如有转发本文,请注明出处

http://blog.csdn.net/u011579138/article/details/51420185

时间: 2024-10-01 10:04:37

Spring MVC:原理与使用的相关文章

spring mvc 原理(一)

文章来自http://jinnianshilongnian.iteye.com/blog/1594806 1:使用spring mvc 的好处 √让我们能非常简单的设计出干净的Web层和薄薄的Web层: √进行更简洁的Web层的开发: √天生与Spring框架集成(如IoC容器.AOP等): √提供强大的约定大于配置的契约式编程支持: √能简单的进行Web层的单元测试: √支持灵活的URL到页面控制器的映射: √非常容易与其他视图技术集成,如Velocity.FreeMarker等等,因为模型数

Spring MVC原理及配置详解

Spring MVC原理及配置 1.Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单.这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中. Spring MVC主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成.他的两个核心是

Spring MVC原理及配置

Spring MVC原理及配置 1. Spring MVC概述 Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单.这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中. Spring MVC主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成. 2. Spr

【Spring】Spring MVC原理及配置详解

1.Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单.这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中. Spring MVC主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成.他的两个核心是两个核心: 处理器映射:选择使用

Spring MVC原理及实例基础扫盲篇

最近 项目中刚接触了SpringMVC,就把这几天看的跟实践的东西写出来吧. 一.首先,先来了解一下SpringMVC到底是个什么样的框架? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发. 二.SpringMVC的工作原理: 1. 客户端请求提交到DispatcherServlet 2. 由Dispatche

Spring MVC 原理

MVC Spring的MVC框架主要由DispatcherServlet.处理器映射.处理器.视图解析器.视图组成. Spring MVC的原理框图: 整个处理过程从一个HTTP请求开始:1)DispatcherServlet接收到请求后,根据对应配置文件中配置的处理器映射,找到对应的处理器映射项(HandlerMapping),根据配置的映射规则,找到对应的处理器(Handler).2)调用相应处理器中的处理方法,处理该请求,处理器处理结束后会将一个ModelAndView类型的数据传给Dis

spring MVC原理

Spring MVC工作流程图 图一 图二  Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获: 2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI).然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回: 3.

Spring mvc 原理浅析

2.2. 数据的绑定 前面说过了,SpringMVC是方法级的映射,那么Spring是如何处理方法签名的,又是如何将表单数据绑定到方法参数中的?下面我们就来讨论这个问题.2.2.1. 处理方法签名 首先,我们可以在方法签名中放入@CookieValue注解参数,Spring自动将Cookie值绑定到参数中:同理@RequestHeader可 以绑定报文头的属性值:同时我们还可以将Servlet API如HttpServletRequest.HttpServletResponse.HttpSess

Spring MVC 原理介绍(执行流程)

Spring MVC工作流程图 图一 图二  Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获: 2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI).然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回: 3.

1 Spring MVC 原理

1. 注解式  Spring MVC 响应流程: 重要的接口和类的简单说明: DispatcherServlet:前端控制器,用于接收请求. HandlerMapping接口:用于处理请求的映射. DefaultAnnotationHandlerMapping:HandlerMapping接口的实现,用于把一个URL映射到具体的Controller类上. HandlerAdapter接口:用于处理请求的映射. AnnotationMethodHandlerAdapter:HandlerAdapt