本文要讲的内容主要包括三部分:
1、SpringIoC、Spring MVC、Mybatis三大框架在项目中的协作;
2、Spring IoC框架讲解;
3、Spring MVC框架讲解。
一、SSM在项目中的协作
1. 先讲下MVC,我们看看下面的图1-1。
MVCM-V-C即Model-View-Controller、模式-视图-控制器。是一种框架模式(不是设计模式),它强制性的使一个应用的输入、处理、输出流程按照Model、Controller、View的方式进行分离,这样一个应用被分成三个层——数据持久层、视图层、业务逻辑层,各自处理自己的任务。
如上图,JSP在视图层输出,Controller和Service在业务逻辑层处理,Mapper和Model在数据持久层输入。
MVC的优点是耦合性低、重用性高、可维护性高。
优点也是缺点,它的主要缺点是增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
2. 我们知道了MVC在项目中是怎么使用的,再来看看Spring(IOC)、Spring MVC和Mybatis在项目中的作用区域。
SSM作用区域2.1 Spring IoC的作用简单来说是为了帮我们创建和管理需要的对象,它在项目中的实现机制是通过@Autowired注解。比如:
@Autowired
private TestService testService;
2.2 Spring MVC的作用就是以MVC的架构形式去协调项目中涉及到的各个层的工作。它协调的方式常用的也是通过各种注解,比如常见的几个:
(1)@Controller 控制器(注入服务,声明Action组件)
(2)@Service 服务(声明Service组件,比如@Service("myMovieLister") )
(3)@Repository(声明Dao组件)
(4)@Component (泛指组件, 当不好归类时使用,必然把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)
(5)@RequestMapping("/menu") 请求映射
2.3 Mybatis的作用是调用和执行XML文件中的SQL,并返回持久层的数据。它执行的一个总体流程为:
加载配置并初始化->接收调用请求->处理操作请求->返回处理结果并将最终的处理结果返回。
二、Spring IoC和Spring MVC
我先分别来讲下Spring IoC和Spring MVC,Mybatis的内容下次再讲。
1. Spring Ioc
我先来问大家一个问题:你是如何去搭讪美女的?
也许你是这样——
(1)先到街上去找长的漂亮身体又好的mm
(2)然后打听她们的兴趣爱好、手机号码、微信号
(3)在想办法认识她们,投其所好
(4)最后,嘿嘿嘿嘿~~
嘿嘿嘿这里的每一步都需要我们自己去设计,这使得这个过程变得复杂深奥。
相对应的,如果我们按照这种方式去设计我们的程序时,将会是如下图 2-1.
按照上面的程序设计,客户端类调用的步骤如下:
(1)创建Controller类
TestController testController = new TestController();
(2)创建Service类
TestService testService = new TestService();
(3)将Service类主动注入到Controller类
testController.setTestService(testService);
这是传统的程序设计。这种方式是极其繁琐的,我们需要在Controller中new Service类,在Service中new Dao类,而且在管理这些new出来的对象时也会有很多内存存储的问题。
当我们使用Spring IoC容器之后,我们再来看看有IoC容器之后的程序设计是怎么样的。
如上图,IoC容器会帮我们去创建我们需要的对象,同时它也会帮我们去管理这些对象的生命周期。
它就像一个婚姻介绍所,婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友。比如长得像范冰冰,身材像林熙雷,唱歌像周杰伦,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。
如果婚介给我们的人选不符合要求,我们就会抛出异常。
整个过程不再由我自己控制,而是由婚介这样一个类似容器的机构来控制。
接下来,我再梳理下IoC容器的知识点。
Ioc—Inversion of Control,即“控制反转”,在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
理解好IoC的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”。那我们来深入分析一下:
(1)谁控制谁,控制什么:传统JavaSE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
(2)为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
讲控制反转,就不得不讲依赖注入啦,那么依赖注入又是什么呢?
DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
(1)谁依赖于谁:当然是应用程序依赖于IoC容器;为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源。
(2)谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
2.Spring MVC
我再来问大家一个问题:
如果我没有柳岩(假设她是我公司的一位设计师)的任何联系方式。我怎么样才能知道她心里是不是喜欢我?以及在这个过程中,Spring MVC能帮我做什么?
要回答这个问题,我们先简单介绍下Spring MVC在处理一个请求的主要流程是怎么样的?
如图2-3
具体执行步骤如下:
1、 首先用户发送请求到前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它(图2-3中的1、2步骤);
2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名)(图2-3中的3、4、5步骤);
3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;(图2-3中的6、7步骤);
4、 前端控制器再次收回控制权,将响应返回给用户,(图2-3中的步骤8);至此整个结束。
在这个过程中有以下几个问题需要解决:
1、 请求如何给前端控制器?
2、 前端控制器如何根据请求信息选择页面控制器进行功能处理?
3、 如何支持多种页面控制器呢?
4、 如何页面控制器如何使用业务对象?
5、 页面控制器如何返回模型数据?
6、 前端控制器如何根据页面控制器返回的逻辑视图名选择具体的视图进行渲染?
7、 不同的视图技术如何使用相应的模型数据?
要想回答上面的问题,我们先要理解清楚Spring MVC的核心架构。如下图:
核心架构的主要流程步骤如下:
1、用户发送请求给DispatcherServlet前端控制器(1),前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制,即第2步;
2、DispatcherServlet前端控制器给HandlerMapping类控制器(2), 类控制器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet前端控制器给HandlerAdapter方法控制器(3),方法控制器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter方法控制器给处理器功能处理方法的调用(4),HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名给ViewResolver视图控制器(5), ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户(6-11),6-11这个过程是在JSP容器中完成。
我们理解清楚Spring MVC的核心架构之后,我们再来回顾一下我们前边提出的问题:
1、请求如何给前端控制器?我们在web.xml中配置了view分发器。
2、前端控制器如何根据请求信息选择页面控制器进行功能处理? 我们配置HandlerMapping进行映射。
3、如何支持多种页面控制器呢?我们配置HandlerAdapter从而支持多种类型的页面控制器。
4、页面控制器如何使用业务对象?利用SpringIoC容器的依赖注入功能。
5、页面控制器如何返回模型数据?使用ModelAndView返回。
6、前端控制器如何根据页面控制器返回的逻辑视图名选择具体的视图进行渲染?使用ViewResolver进行解析。
7、不同的视图技术如何使用相应的模型数据?因为Model是一个Map数据结构,很容易支持其他视图技术。
在以上过程中,我们提到了Spring MVC的核心接口主要有4个,我们来一一讲解。
1、DispatcherServlet接口:
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
2、HandlerMapping接口:
能够完成客户请求到Controller映射。
3、HandlerAdapter接口:
处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名)。
4、ViewResolver接口:
Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。
回到最开始我们提到的问题:柳岩是否喜欢我?如图2-4
柳岩是否喜欢我?SSM三大框架第一篇,做个小科普。
网友评论