MVC是开发Web应用程序的通用架构方式:
前端控制器是spring 团队贡献给java社区的一种设计模式,一种MVC的实现方式。
前端控制器的图如下图所示:
以生活中的场景为例:
MVC的本质:核心思想是业务数据抽取同业务数据呈现相分离(相分离:这是一种简化,将复杂的东西相分离了,可以将某个被分离出的场景更加简洁的去表示它,更利于编程的实现)
MVC:Model-View-Controller
Model:模型层业务数据的信息的表示,关注支撑业务的信息构成,通常是多个业务实体的组合,如Course类(包含id,title)
View:视图层(为用户提供UI,重点关注数据呈现)
Controller:连接View和Model,调用业务逻辑产生合适的数据(Model),传递数据给视图层用于呈现
1、MVC是一种架构模式,程序分层,分工合作,相互独立又协同工作。
(1)程序分层,分工合作:MVC将程序分成三层:模型层,视图层,控制层,有了程序的分工合作,程序员就有了工种的分离(前端工程师和后端工程师/后端逻辑开发和前端页面开发)
(2)相互独立,协同工作:如在前端控制器的图中,Controller和Viewer并不耦合,之间可以没有任何联系,但是需要根据页面的要求产生合适的数据,而页面呈现又不能脱离业务逻辑凭空展开一定是基于业务逻辑的,所以它们之间是即相互独立又协同工作的。
2、MVC是一种思考方式?
前面通过MVC将程序分层了,分成了模型层,视图层,控制器层,那么就需要在这个层面上进行思考,在模型层上去思考将给用户展示什么信息来构成模型,在视图层需要考虑如何将这些数据布局,怎么以更加优美合理的方式展现给用户,控制器层需要考虑调用哪些业务逻辑,使得我们可以呈现给用户正确的数据,效率更高,性能更好。
1. DispatcherServlet:Spring MVC做为一种前端控制器的实现形式,DispatcherServlet就是它的前端控制器,前端也就是浏览器端的请求就是通过DispatcherServlet进行分发到达合适的Controller来生产我们所需要的业务数据Model,这model再通过DispatcherServlet进行传递,传递给View完成最终的页面呈现。因此MVC将数据的业务逻辑和页面实现了分离其实核心就是通过DispatcherServlet来实现的。
2.Controller:就是MVC中的C,就是调用业务逻辑生成model的地方。
3.HandlerAdapter:Handler是DispatcherServlet内部使用的类,其实就是Controller的一个表现形式,在Spring MVC中并没有一个接口叫Controller,但是他有一个标签,这个标签为我们识别一个Controller而引入的,没有Controller这个接口,或者抽象类这种类似于接口的东西,DispatcherServlet如何识别Controller就是通过Handler,在DispatcherServlet中,调用Controller最终都是以Handler的形式出现的。HandlerAdapter,就是一个适配器模式,就是将不同类型的Handler适配成DispatcherServlet可以使用的Handler,这样DispatcherServlet就可以很轻松的调用控制器。
4. HandlerInterceptor:Interceptor就是拦截器的意思,他其实就是在我们需要被拦截对象的两侧,加一些东西。HandlerInterceptor是一个接口有三个方法,preHandle,postHandle,afterCompletion,如果配置了这个类并提供了实现,就可以在真正调用Controller之前、之后以及最终在我们model发送到页面,或者view完成了呈现之后可以做一些事情。
5.HandlerMapping: Handler是DispatcherServlet调用Controller的一种中间过渡对象。Mapping就是DispatcherServlet(前端控制器)与我们Controller之间映射关系的一种类。Handler Mapping就是告诉DispatcherServlet这个请求到达之后由哪一个Controller来响应这个请求。之前提到HandlerInterceptor会对我们的Controller加一些料,这也是HandlerMapping需要考虑的事情。简单来说就是,HandlerMapping工作完成之后可以给DispatcherServlet一个HandlerAdapter,这个HandlerAdapter里面就包括了核心的内容是某一个具体的Controller的实例,以及这个Controller需要被包裹的HandlerInterceptor,它们会构成一个执行联调往下走。
6. HandlerExecutionChain:就是上面说到的,HandlerMapping返回给DispatcherServlet的东西其实包括Handler Adapter和Interceptor,它们之间构成了一个执行链条,它首先会执行HandlerInterceptor的preHandle然后去调用Controller里的某个业务方法,然后再执行postHandle最后是afterCompletion。有兴趣去看源代码的话,发现并不复杂,只是用到了java的反射机制。
7.ModelAndView :这是Spring MVC中对Model的一种表现形式,Spring中相关的类还有Model类,你也可以使用java中的Map类实现Model的功能。如果你在Controller中见到有人用Model,Map这样其他的类,DispatcherServlet都会把它转化为ModelAndView ,所以认为他是Model的具体表现形式。
8.ViewResolver:视图解析器,告诉DispatcherServlet需要用哪个视图来进行视图的呈现,因此它的作用就是:根据我们的配置,找出那一个我们需要的视图对象,比如我们的JSTL,JSP
9.View :刚刚说过有很多view,比如JSTL,jsp,这些view是干嘛的呢?就是负责呈现页面
DispatcherServlet居于核心的地位,是使者是桥梁,.Controller,Spring MVC中的C,View最后我们用户想看到的东西,V。
访问过程:Request从浏览器端过来,第一个到达DispatcherServlet,因为它是一个Servlet,所有的request它都可以拦截到,DispatcherServlet拦截到一个request,然后它就要去找我们的Controller,如何找,就是看mapping,就有一个HandlerMapping,因此DispatcherServlet就将功能代理给了HandlerMapping,HandlerMapping,根据自己的配置知识,可以通过标签来做,可以通过一些标签来告诉我们的HandlerMapping,哪一个Controller是我们要的,因此它可以很容易的找到我们的Controller,不光是Controller还有HandlerInterceptor,这个时候HandlerMapping找到了我们的Controller和HandlerInterceptor,把他们形成了HandlerExecutionChain,作为Handler/HandlerAdapter,返回给了我们DispatcherServlet,然后DispatcherServlet会调用Handler/HandlerAdapter,而我们写Controller的目的就是为了生成我们的模型,为我们页面呈现提供一些显示的料,模型生成之后它会返回给DispatcherServlet,然后就需要去显示,就是需要ViewResolver,ViewResolver告诉DispatcherServlet需要用哪个视图来进行视图的呈现,因此我们的DispatcherServlet通过调研ViewResolver的方法返回我们View的对象,让后我们的ModelAndView (模型数据)被传递给了view完成了我们页面的呈现,这是就可以在页面上看到用户界面了
Request,Response我们不需要考虑
DispatcherServlet:很重要,但是不需要我们写,Spring MVC为我们提供了现成的实现,只需要配置一下就可以了
HandlerMapping:很复杂,但是我们并不需要知道怎么去Mapping,只需要怎么配置就可以了,已经有很多的实现为我们提供了,我们只需要把它配到我们的配置文件中就可以了。
Controller:我们需要写一些东西,因为Spring是不知道你的业务逻辑需要,作为一个业务程序开发员你是对业务最清楚的,我们应该如何调用我们的业务逻辑生成我们的Model,就是我们要手动编写的地方。
HandlerInterceptor是个接口需要的话就去实现,不需要的话就不用管,并不是所有的场景都需要在Controller调用之前之后干点什么
Handler/HandlerAdapter:不需要我们管,可以忽略掉
ModelAndView :只是一个类,也可以使用Map这种简单的东西,把一个key和一个内容放进去就可以了,Spring MVC或者DispatcherServlet可以自己为你去转换成它需要的东西
ViewResolver:也是有一大堆的实现和HandlerMapping差不多,只需要知道你使用哪一种类型就可以了,View也是一样的我们不需要去管具体的呈现,只需要告诉它是哪一个就好了,比如告诉它是哪一个jsp就可以了,中间的过程,由这个View对象自动的去完成了