当前流行的mvc框架主要有struts1,webwork,struts2,spring mvc,jsf。Struts 1 是最早的mvc框架,之后出来的webwork涉及思想非常优秀但是很遗憾,没有得到太多的应用。在struts1和webwork的基础上,发展起来了struts2的框架,这是目前主要使用的框架之一,jsf是一个事件驱动的mvc框架。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。Spring mvc的功能组件划分细致、灵活和低耦合,将是mvc的发展方向。
Mvc框架都做了什么
- 以controller为中心,完成对系统流程的控制管理
- 从请求中收集数据
- 对传入的参数进行验证
- 根据请求调用相应的业务逻辑完成数据处理(model)
- 将结果返回给视图
- 针对不同的视图技术提供不同的视图解析方案,国际化支持
- 通过拦截器链实现面向方面编程(AOP)完成系统级控制
Spring mvc的核心组件
每一个组件其实就是一组java接口,或者有框架自己实现,或者是自己实现
- Dispatcher Servlet(servlet的分发器,总的控制中心,根据映射关系Handler Mapping分发到到自己实现的servlet)
- Handler Mapping(将具体的请求派发给具体的控制器)
- Controller(处理自己的业务逻辑)
- ViewResolve (视图解析映射,将逻辑视图映射到具体的实现类,策略)& View(视图类)
- Interceptors (拦截器链)
- localResolver(国际化)
- Validate(验证)
Spring的核心原理
- 用户发送请求给服务器。url:user.do
- 服务器收到请求。发现DispatchServlet可以处理。于是调用DispatchServlet。
- DispatchServlet内部,通过HandleMapping查查这个url有没有对应的Controller。如果有,则调用Controller
- Controller开始执行
- Controller执行完毕后,如果返回字符串,则ViewResolver将字符串转化成相应的视图对象;如果返回 ModelAndView对象,该对象本身就包含了视图对象信息。
- ViewResolver 将执视图对象中的数据,输出给服务器。
- 服务器将数据输出给客户端。
简单的理解就是:
Spring MVC内部相关处理逻辑:
http请求被servlet-mapping转发到框架管理,DispatchServlet接收这个请求,并根据Handler Mapping进行映射,找到处理他的servlet也就是controller,controller在处理这个请求的前后可能会被拦截器拦截,来完成一些其他工作,如记录日志,权限管理等等,并且spring mvc框架提供了数据验证的功能,可以在数据传入的时候进行验证。当controller处理完请求后,建立好数据模型,并返回一个逻辑视图,由view Resolvor进行视图解析,找到真正的显示视图,向用户呈现数据。
Demo
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 4,Handler Mapping组件,
完成具体的请求到具体的controller的映射 -->
<!-- 当加载这个配置文件的时候,会首先实例化以HandlerMapping结尾的类,如下面的SimpleUrlHandlerMapping类,
然后在它里面查找映射关系 -->
<!-- SimpleUrlHandlerMapping是基于url的控制器 -->
<bean class = "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!-- 映射属性 -->
<property name = "mappings">
<!-- 映射键值对 -->
<props>
<!-- 当请求时start.test时,将控制交由startController这个controller处理 -->
<prop key="start.test">startController</prop>
<!-- -->
<prop key="login.test">loginController</prop>
<prop key="logout.test">logoutController</prop>
<!--<prop key="addUser.test">addUserController</prop>-->
<!-- <prop key="addUserAction.test">addUserActionController1</prop> -->
<prop key="addUserAction.test">addUserActionController2</prop>
<!-- 这里使用了一个formcontroller,这个controller很特殊-->
<!-- <prop key="addUser.test">addUserActionController3</prop> -->
<prop key="toAdd.test">addUserActionController4</prop>
<prop key="addUserAction.test">addUserActionController4</prop>
</props>
</property>
</bean>
<!-- 基于类名的handlermapping,比如请求abc.test,则mapping会自动映射到AbcController的控制器,可以简化映射的配置
<bean class = "org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>
基于beanname的映射,上面是基于class的映射
<bean class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
-->
<!-- 这个controller实现直接映射(参数化的视图控制器),也就是说只是返回一个逻辑视图名“login”(view = “login”),
然后由View Resolver解析为login.jsp。不需要实现自己的controller,spring框架自己提供了 -->
<bean id = "loginController" class = "org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName" value = "login"></property>
</bean>
<!-- 这个controller是一个更加简化的controller,基于文件名的视图控制器,它直接根据请求的文件名,来返回视图的逻辑名,
逻辑名就是请求文件名,如这里如果请求logout.test,则它返回一个“logout” ,之后再经由view resolver解析为logout.jsp-->
<bean id = "logoutController" class = "org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>
<!-- 请求addUser.test,这里会直接将请求的文件名,作为逻辑视图名返回,注意这里返回的是请求的文件名,而不是这里的控制器名的前半部分 -->
<bean id = "addUserController" class = "org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>
<!-- 3,实现和注册我们的controller,controller组件 -->
<bean id= "startController" class = "hust.StartController"></bean>
<!-- 使用继承自AbstractController的控制器 -->
<bean id = "addUserActionController1" class = "hust.AddUserActionController1"></bean>
<!-- 配置自定义属性编辑器,加入到一个map里面去,map的key是要转换的类型的全名称,value是我们自己写的转换器
这种方法有点问题,暂时还没有解决
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="hust.MyEditor">
<property name="pattern" value="yyyy-MM-dd"/>
</bean>
</entry>
</map>
</property>
</bean>
-->
<!-- 使用继承自AbstractCommandController的控制器 这里还涉及了数据绑定-->
<bean id = "addUserActionController2" class = "hust.AddUserActionController2">
<!-- 使用反射机制,自动注入时需要制定注入的类的类型 -->
<property name="commandClass" value = "hust.User"></property>
</bean>
<!-- SimpleFormController是AbstractFormController的具体实现,
允许你在配置文件里通过successView和formView属性来配置成功视图(表单成功提交后要转向的页面)和表单视图(显示表单的页面)
它可以处理表单流程
-->
<bean id = "addUserActionController3" class = "hust.AddUserActionController3">
<!-- 使用反射机制,自动注入时需要制定注入的类的类型 -->
<property name="commandClass" value = "hust.User"></property>
<!-- 当第一次以get方法请求页面的时候,他不会执行onSubmit方法,但是referenceData会被执行,返回视图需要的数据,同时返回一个addUser的逻辑视图
当提交表单的时候,还是会到这个controller,但是这是是以post方式提交的,所以它只会执行onSubmit方法
也就是说对于同一个请求他会根据不同的请求方式,给出不同的响应方式
-->
<property name="formView" value = "addUser"></property>
<property name="successView" value = "addUserSuccess"></property>
</bean>
<bean id = "addUserActionController4" class = "hust.AddUserActionController4">
<!-- 方法名解析器 -->
<property name="methodNameResolver">
<!-- 根据请求的路劲来解析响应的方法调用 -->
<bean class = "org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver"></bean>
</property>
</bean>
<bean id = "addUserServController" class = "hust.UserController">
<!-- 使用反射机制,自动注入 -->
<property name="commandClass" value = "hust.User"></property>
</bean>
<!-- resolve是一种策略,完成逻辑名称(字符串)到view真实视图的映射,真正的处理是由 viewclass来完成的-->
<!-- 基于url的视图解析器 ViewResolve & View 组件-->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<!-- Resolver和view 要结合使用,这里试试使用jsp作为视图层,jstl在jsp显示的时候可以完成国际化的处理-->
<!-- 在我们的例子中,viewclass 并没有做什么事情, -->
<property name="viewClass" value = "org.springframework.web.servlet.view.JstlView"></property>
<!-- 指定请求的前缀 -->
<property name="prefix" value = "/WEB-INF/jsp/"></property>
<!-- 指定请求的后缀 -->
<property name="suffix" value = ".jsp"></property>
<!-- 对于名字为“start”的逻辑视图,按照上面的配置,会进行拼装成/WEB-INF/jsp/start.jsp,
在spring框架内部会使用request.forward()方法实现跳转 -->
</bean>
</beans>
本文详细介绍了Spring MVC框架的主要功能组件、核心原理及配置示例,包括控制器、视图解析、国际化支持等关键部分。通过具体XML配置文件展示了如何实现基于XML的Spring MVC应用,为开发者提供了一套全面的实践指南。
37万+

被折叠的 条评论
为什么被折叠?



