Spring 学习笔记(3)Spring MVC
一、什么是 MVC
MVC 实际上就是一种设计模式 Model-View-Controller
- Model 模型其实就是数据,Dao,Bean 等等
- View 视图就是所看到的东西,网页,JSP,展示模型中的数据,包括数据逻辑的处理和数据操作(数据库中存取数据)
- Controller 控制器就是将不同的数据(Model)显示在不同的视图(View)上
1. Model1 时代
它是在 JSP + Bean (Model + View) 基础上升级演变过来的,称之为 Model1,相对于 MVC 而言,它是将 Controller 和 View 两者结合在一起。前后端高度耦合,代码难以复用
正是因此,MVC 随之抽象出来,形成了 Servlet + JSP + JavaBean 的新开发模式
2. Model2 时代
这时,将 JSP 中的控制功能抽象提取出来,形成 Servlet ,用于处理用户的数据请求。
大大的提高了代码的可重用性,三个模块相互独立,降低了各模块的耦合度。
二、什么是 SpringMVC
SpringMVC 是 Spring 的一个子项目,它其实是为三层架构中的表示层开发提供的一整套完备的解决方案
三层架构分为表示层、业务逻辑层、数据访问层。表示层主要表示出前台页面和后台 servlet
优点:
- 基于原生的 Servlet, 通过了功能强大的前端控制器 DispatcherServlet,对请求和响应进行统一处理
- 代码清新简洁,而且是插拔式组件即插即用
- 性能卓著,适合大型互联网项目要求
问题:MVC 和 三层架构的区别?
这里引用一下回答,原地址在这
其实它们相同的地方在于他们都有一个表现层。
但是他们不同的地方在于其他的两个层。
首先先解释一下MVC。V即View.是视图的意思。C即Controler.是控制器的意思。而M即Model,是模型的意思。这三个里.最不容易理解的应该是Model.就是什么是Model,而为什么叫Model。我先不说为什么叫Model,先解释Controler。
Controller是控制器的意思,所谓控制器,就是将用户请求转发给模型层,经过处理后把结果返回到界面展现的一个中间层,那么Controler到底管什么工作呢?先不说.先来看下在Java Web中这三个层一般的定义,一般在Java Web里,JSP充当V,Servlet充当C,JavaBean充当M,这里的Servlet管什么工作呢?接受输入,转到Model层去处理,处理结果保存后转发到JSP,然后展现数据。所以它的功能就是控制器的基本功能,它就管转发,在V和M之间转来转去。
再来说说M,即Model,在Java Web里说的是JavaBean,我认识的很多人都把JavaBean误认为是实体类,其实JavaBean有比实体类更丰富的定义,在JavaBean中除了其属性和字段,还可以有行为及其事件,JavaBean可以理解为普通Java对象。Java普通对象,就是符合Java规范的所有对象,这和实体类完全是两回事。所以,我认为在MVC中。业务逻辑和数据访问应该放在Model层,也就是V负责展示数据,Controler除了转发不做业务逻辑。真正的逻辑事务,数据访问,甚至算法都放到Model去。
再说三层架构。三层其实很好理解,界面,业务,数据访问,就这三个,从字面都可以理解出它们的意思。我要说的是它和MVC的区别。在三层架构中没有定义Controler的概念。这是我认为最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。
当然了。在三层中也提到了Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是已实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。不一样的概念。虽然名字一样
三、利用一个 HelloSpringMVC 程序来跟踪 SpringMVC 的请求过程
先看看 SpringMVC 的请求过程:
1. HTTP 请求到 DispatcherServlet
用户发起一个 Request 请求,这个请求会到达 DispatcherServlet ,经过相应的处理传送到对应的 Handler 处理器(Controller)。首先查看对应的 web.xml 文件的 Servlet 部分代码:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<!--拦截所有的请求,将这些请求发送给 Spring MVC 控制器-->
<url-pattern>/</url-pattern>
</servlet-mapping>
2. DispatcherServlet 请求处理器映射器,查找对应的控制器
将 3, 4 ,5 步骤合起来讲,这一部分我们先看 dispatcher-servlet.xml 文件中的内容:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="simpleUrlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- /hello 路径的请求交给 id 为 helloController 的控制器处理-->
<prop key="/hello">helloController</prop>
</props>
</property>
</bean>
<bean id="helloController" class="controller.HelloController"></bean>
</beans>
处理器映射器会通过在浏览器中输入的 URL 信息返回一个执行链,然后 HandlerAdapter 根据执行链中的 Handler 的信息找到对应的 Handler 。比如我们在输入框输入https://localhost:8080/hello
处理器映射器则会对应将这个信息传送给 HelloController 控制器进行处理。
后期可以用注解来代替这种方式。
3. Handler 处理器
对应 6,7 步骤,这一部分就是我们常见的 Controller 代码,处理相应的逻辑。
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView("index.jsp");
modelAndView.addObject("message", "Hello SpringMVC");
return modelAndView;
}
}
在处理完会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息), HandlerAdapter 会继续将这个对象返回给 DispatcherServlet 。
4. ViewResolver 视图解析器
这部分对应 8,9 步骤 DispatcherServlet 会将接收到的 ModelAndView 传递给 ViewResolver , 让其对该对象进行解析,并且根据 View 信息匹配到相应的视图结果,并将 View 返回给 DispatcherServlet 。
注意,这里传递的仅仅是一个逻辑名称,这个名称将会用来查找产生结果的真正视图
也就是这一行代码
ModelAndView modelAndView = new ModelAndView("index.jsp");
5. View 视图
DispatcherServlet 根据接收到的 View 视图,对视图进行渲染,并且将 Model 中的模型数据填充到 View 视图中的 request 域中,生成最终的视图 View。视图将这些结果显示到浏览器中。