美文网首页我爱编程
深入浅出SpringMVC(小白篇)2

深入浅出SpringMVC(小白篇)2

作者: qinqiang2000 | 来源:发表于2018-06-21 16:54 被阅读0次

深入浅出SpringMVC(小白篇)1
深入浅出SpringMVC(小白篇)3

四. MVC框架时代1-Spring MVC tutorial

Java界的MVC框架,很大目的是让后端码农更专注于纯java开发(业务逻辑实现),少操心其他部分。按这个思路,上一篇文章提到的JSP Model2中,虽视图和模型、控制逻辑和展示逻辑分离了,但仍然存在很多待改进的地方:

  1. 控制器的逻辑可能比较复杂:每个模块基本需要一个控制器,如登录模块对接LoginServlet,新增用户模块对AddUserServlet等;
  2. 请求参数到模型的封装比较麻烦:http协议传输都是文本形式,到Servlet后需要手工将它们转到一个有不同类型的javabean(如上篇练习题的AccountBean),繁琐且无技术含量;
  3. 视图的选择严重依赖于Servlet API:如resp.sendRedirect("success.jsp"), 很难更换视图,比如我要支持Excel、PDF视图等等;
  4. 给视图传入用于展示的模型数据也依赖于Servlet API.

还有不少其它缺陷,就不一一列了。总的来说,需要进一步演进,降低码农负担。其中Struts、SpringMVC等框架的出现就是为了解决这些缺陷。先不进入具体框架细节,试着假定由我们来改进,应该如何做,请思考一下。
如果没有思路,分享一个给你,一个面对任何复杂问题时,屡试不爽的思考模式:分而治之

  1. 控制器过于复杂问题:那就将其分为多个子控制器呗,各负责一部分控制逻辑。1)分离的客户端请求与响应功能给单一控制器,暂且叫做Front Controller。它是所有请求和响应的中心,但只转发不做其他事情;2)客户请求与功能处理的控制器的映射逻辑,也单独放入一个控制器,暂叫做Application Controller 3)功能处理代码,如收集参数、转调javabean业务对象,返回逻辑视图名交给前端控制器等,放到另外的controller,暂叫Page Controller或handler或Command(熟悉设计模块的小白应该可想到这里就是个command模式)
  2. 请求参数转成模型麻烦:那就单独设计一个模块,专门将http文本型参数转为javabean内部属性对应的类型,暂叫DataBinder
  3. 控制和视图强耦合问题:那就让这两者用一个通用的数据结构进行交互,比如用字符串来表示一个视图逻辑名,用jsp还是其他视图模板,控制器不关心,而是由一个单独的模块处理,暂叫它ViewResolver。ViewResolver根据视图逻辑名找到相应具体视图模板并结合模型数据进行解析。如控制器给视图模块传“success”字符串,ViewResolver根据配置及工程目录下文件名,找到success.jsp,并用jsp视图解析器解析success.jsp此模板。

底下是根据这些思路画的一个示意图,哈哈,SpringMVC就是这么实现的喔( 注:这里用HandlerMapping替代Application Controller,作用差不多)。

Spring-mvc-flow.jpg
上图只有橙色需自己实现,其他组件框架都实现好了:)包括Front Controller(也叫DispatcherServlet),DataBinder(未画出),ViewResolver,HandlerMapping等都不需要码农门自己写啦,适当配置一下即可。
底下是官方reference的图,更加简洁。
Web MVC的High Level视图

小结:我们分析了原装java web模式的缺陷,并思考如何了去改进,然后引出SpringMVC的基本框架图,同时示意了用SpringMVC写程序的套路:写业务Model,写Controller,写View(如jsp文件)和配置其他组件(如web.xml,x-servlet.xml)

做个练习吧,白手搭建java web应用_基于maven+tomcat+spring mvc。里面一些语法不懂的话暂时不用管(毕竟你没学spring),后面也有一些解释,也可以翻spring的reference或百度;另外该框架依赖很多库,手工搞很痛苦,所以今后练习用Maven管理依赖。Maven环境配置可以找组长、度娘或这里

四. MVC框架时代2-More on Spring MVC
快速了解Spring
后面内容开始需要懂一点Spring知识,毕竟SpringMVC是Spring Framwork一部分。
Spring有很多东西,讲完可以写一本书,但这里只讲最重要的一点(没有之一):dependency injection (DI,依赖注入)。DI是一个设计模式:将代码所依赖的对象与代码本身分开。Spring实现了DI,可以让你将一堆对象(也叫beans)通过配置(xml或注解)关联起来。举例:你要写了一个MySevice的类需要调用一个data-access object (DAO) bean来存储数据,大概代码如下:

public class MyService {
   private MyDao dao;
   public void setMyDao( MyDao dao ) {
      this.dao = dao;
   }
   public Widget businessMethod() {
      return dao.doBusinessThing();
   }
}

传统方式是dao这个对象需要你手工去创建(new)它,然后通过setMyDao赋值给MyService的一个对象(这个对象也需在某个地方创建),这分散了你精力,难以专注业务逻辑编写。用了Spring,通过xml或注解,MyDao和MyService对象的创建、setMyDao的调用都是Spring帮你搞定了,你可更安心的写业务逻辑。
一句话,Spring的核心价值,是将代码和配置分开,从而构建出一个更加容易管理的应用程序。

注解替代xml
上面练习中,关于配置,只需要记住底下两点即可:web.xml是配置Front Controller的,另外的applicationContext.xml用于配置剩下组件,包括(但不是必须)ViewResolver、HandlerMapping、HandlerAdapter及Controller的包路径。
上面的xml配置也可以基于java注解的配置所取代,注解方式更受码农喜欢,因此需要练习使用:Spring MVC with Java Configs instead of XML configs .提示:Spring的@Bean注解用于告诉方法:请返回的一个对象,该对象将由Spring容器管理;程序其他地方用到该对象,只需在引用处加上@Autowire。

更详细的流程解释
做了这几个练习后,我们可理解多一点的内部细节了,具体如下。当然没时间可以不看,不影响动手写代码。

  1. 步骤①, DispatcherServlet作为前端控制器, 统一的请求接收点, 控制全局的请求流程. 接收到用户请求, 自己不做处理, 而是将请求委托给其他的处理器进行处理.
  2. 步骤②③, DispatcherServlet通过HandlerMapping(处理映射器), 将请求映射为一个HandlerExecutionChain对象, 其中包括了页面控制器和对其配置的拦截器.
  3. 步骤④, DispatcherServlet通过获得的Handler(处理器, 页面控制器, Controller), 查找一个合适的HandlerAdapter(处理器适配器), 通过这个HandlerAdapter调用Handler实际处理请求的方法.
  4. 步骤⑤, 提取请求中的模型数据, 调用Handler实际处理请求的方法. 在调用方法时, 填充参数过程中, spring会根据配置做一些工作, 如: 数据转换, 数据格式化, 数据验证等.(更具体一点,Spring通过DataBinder与PropertyEditor一起进行数据转换)
  5. 步骤⑥⑦, Handler执行完成后, 将返回一个ModelAndView对象给DispatherServlet. ModelAndView对象中包含逻辑视图名或逻辑视图名和模型.
  6. 步骤⑧, 根据ModelAndView对象选择一个合适的ViewResolver(视图解析器).
  7. 步骤⑨, ViewResolver将ModelAndView中的逻辑视图名解释成View对象. ViewResolver也是接口, 同样采用了策略模式, 这样就很容易切换其他的视图类型.
  8. 步骤⑩⑪, 渲染视图时, 将Model数据传入视图中, 这里的Model数据是一个Map, 容易与各种视图类型相结合.
  9. 步骤⑫, 最后, 由DispatcherServlet将最终的响应结果返回给用户.

通过这些步骤, springmvc依赖几个对象共同完成了请求到响应的工作流程, 对于开发者来说, 这些对象是不可见的, 开发者只需要关心Handler(Controller)中对请求的处理业务即可.

Spring MVC常用注解
一些Spring MVC注解语法是需要去记忆,本想自己写一点内容,但发现这篇文章写的更详细,所以请看这里。记不住没关系,写Controller的时候,查一下就是了,只要需理解和记住web服务端开发的演进过程和SpringMVC基本框架。

四. MVC框架时代3-Restful Spring MVC
本文开头提过,后端mvc框架最大目的是让后端码农更专注业务逻辑代码,虽然SpringMVC做了很大努力,但视图相关模板编写(如JSP)工作仍得让后端参与,怎么办呢? 我们线分析一下SpringMVC视图处理过程:

SpringMVC视图处理
小白需要理解视图处理的核心是两动作:How和What。How是如何展示数据,由模板实现;What是展示什么数据。
What是业务逻辑紧相关,后端码农无法规避;How是前端展示相关,不应该由写业务逻辑的人直接参与。那问题变成:如何把How独立出来,更进一步的问题是模板和数据放哪里结合?请思考一阵子再继续往下看。
思路其实很简单,既然后端码农不适合写模板,那就只能由前端码农写啦;前端码农代码一般放哪里运行?浏览器呀。Yes,答案是由浏览器完成模板和数据,于是图变成底下这样:
Restful风格的架构
上图就是Restful SpringMVC风格的典型架构,静态页面也可以放入Servlet容器的。
后端码农看到这个画面,是不是很爽:)因为前端人员负责模板(一般是js+html静态页面)编写和与的数据整合,你只需接受请求,返回数据(json或xml格式)即可。
世道轮回啊,貌似返回原始时代的简约(而不简单)画风了。
做个简单练习吧:Spring 4 MVC RESTful Web Service 练习说明:1)不必下载RESTClient,在浏览器输入url即可;2)简单起见,模板这块就不写了,js搞熟了自己补上去吧

小结

  • 我们从Java传统MVC架构的缺陷出发,思考了一个简单的改进方案,正巧和SpringMVC的核心方案一致;接着进一步了解了SpringMVC的细节,并通过练习加深印象;最后介绍的Restful风格架构,让我们更专注业务逻辑实现。SpringMVC整个设计是相当灵活,但事情永远有两面性,灵活的代价是复杂的配置。
  • 相信小白们和我当初学SpringMVC时的心态是一样的,太TMD麻烦,弄个Helloworld还搞这么多配置,这么多类,耗时易错(间接影响了我们谈恋爱的时间)。
  • 是的,即使有Spring框架(包含SpringMVC),开发JavaEE的系统还是过于复杂和笨重,这段时间Python、Ruby On Rails、PHP等慢慢蚕食JavaEE的市场,JavaEE消沉趋势不可避免,如果没有下文说的一个创新性项目的出现的话。

相关文章

网友评论

    本文标题:深入浅出SpringMVC(小白篇)2

    本文链接:https://www.haomeiwen.com/subject/zqkbeftx.html