深入SpringMVC

Spring MVC总体设计

在一个工程中如果想要使用 SpringMVC的话,只需要两个步骤

1.在web.xml中配置一个DispatcherServlet。需要配置一个org.springframework.web.servlet.DispatcherServlet的servlet。
2..在spring-mvc.xml中配置:三个核心组件的bean配置。处理器适配:HandlerAdapter,处理核心类中的核心方法。映射处理器:HandlerMapping,根据请求的url地址进行解析。视图解析:ViewResolver,告诉spring容器视图层位置与视图层文件格式。

对于spring MVC框架中,有三个组件是用户必须定义和扩展的:

  • 定义URL映射规则:handlerMapping
  • 实现业务逻辑的handler实例对象:handlerAdapter
  • 渲染模版资源:ViewResolver

    SpringMVC主要八个组件,除以上三个核心组件外,

  • MultipartResolver 文件上传

  • HandlerExceptionResolver 出错处理
  • initLocaleResolver 处理国际化
  • ThemeResolver 定义主题
  • RequestToViewNameTransLator 替换指定ViewName

初始化8个组件的Bean对象保存在DispatcherServlet类中。

Control设计

Spring MVC的control主要由HandlerMapping和HandlerAdapters两个组件提供。
HandlerMapping负责映射用户的URL和对应的处理类,HandlerMapping并没有规定这个URL与应用的处理类如何映射,在HandlerMapping 接口中只定义了根据一个URL必须返回一个由HandlerExecutioChain代表的处理链,我们可以在这个处理链中添加任意的HandlerAdapters实例来处理这个URL对应的请求,这种设计思路和在Servlet规范中Filter处理是类似的。

1.HandlerMapping 初始化
它的作用就是帮助我们管理URL和处理类的映射关系,简单的理解,就是将一个或多个URL映射到一个或多个Spring Bean中。
初始化工作完成的两个最重要的工作就是将URL和Handler的对应关系保存在handlerMap集合中,并将所有的interceptors对象保存在adaptedInterceptors数组中,等请求到来的时候执行所有的adaptedIntercoptors数组中的interceptor对象。所有的interceptor必须实现HandlerInterceptor接口。

2.HandlerAdapter的初始化
HandlerMapping 可以完成URL与Handler的映射关系,那么HandlerAdapter就可以帮助自定义各种handler了。因为SpringMVC首先帮助我们把特别的URL对应到一个Handler,那么这个Handler必定要符合某种规则,最常见的方法就是我们的所有handler都继承某个接口,然后SpringMVC 自然就调用这个接口中定义的特性方法。

Spring MVC中提供了如下三个典型的简单HandlerAdapter实现类。
a.SimpleServletHandlerAdapter:可以继承HttpRequestHandler接口,所有的Handler可以实现其void handleRequest(HttpServletRequest request, HttpServletResponse response)方法,这个方法没有返回值。
b.SimpleControllerHandlerAdapter:可以继承Controller接口,所有的Handler可以实现其public ModelAndView handle(HttpServletRequest request, HttpServletRes ponse response, Object handler)方法,该方法会返回ModelAndView对象,用于后续的模板渲染。
c.SimpleServletHandlerAdapter:可以直接继承Servlet接口,可以将一个Servlet作为一个Handler来处理这个请求。
对于handlerAdapter的初始化没有什么特别之处,只是简单的创建一个handlerAdapter对象,将这个对象保存在DispatcherServlet的HandlerAdapters集合中。当Spring MVC将某个URL对应到某个Handler时候,在handlerAdapters集合中查询那个handlerAdapter对象supports这个Handler,handlerAdapter对象将会被返回,用了调用这个handlerAdapter接口对应的方法。

3.control的调用逻辑

整个Spring MVC的调用是从DispatcherServlet的doService方法开始的,在doService方法中会将ApplicationContext、localeResolver、themeResolver等对象添加到request中便于在后面使用,接着就调用doDispatch方法,这个方法是主要的处理用户请求的地方。

对于control的处理关键就是:DispatcherServlet的handlerMappings集合中根据请求的URL匹配每一个handlerMapping对象中的某个handler,匹配成功之后将会返回这个handler的处理连接handlerExecutionChain对象。而这个handlerExecutionChain对象中将会包含用户自定义的多个handlerInterceptor对象。
对于handlerInterceptor接口中定义的三个方法中,preHandler和postHandler分别在handler的执行前和执行后执行,afterCompletion在view渲染完成、在DispatcherServlet返回之前执行。当preHandler返回false时,当前的请求将在执行完afterCompletion后直接返回,handler也将不会执行。

在类HandlerExecutionChain中的getHandler()方法是返回object对象的;这里的handler是没有类型的,handler的类型是由handlerAdapter决定的。dispatcherServlet会根据handlerAdapters集合中第一个支持该handler对象的HandlerAdapter对象。接下来去执行handler对象的相应方法了,如果该handler对象的相应方法返回一个ModelAndView对象(SampleControllerHandlerAdapter)接下来就是去执行View渲染了。

这里写图片描述

Modle设计

如果handler返回了ModelAndView对象,那么说明Handler需要传一个Model实例给view去渲染模版。除了渲染页面需要model实例,在业务逻辑层通常也有Model实例。

ModelAndView对象是连接业务逻辑层与view展示层的桥梁,对spring MVC来说它也是连接Handler与view的桥梁。ModelAndView对象顾名思义会持有一个ModelMap对象和一个View对象或者View的名称(譬如hello.vm模板名字)。ModelMap对象就是执行模版渲染时候所需要的变量对应的实例,如jsp的通过request.getAttribute(String)获取的JSTL标签名对应的对象。velocity中context.get(String)获取$foo对应的变量实例。

ModelMap其实也是一个Map,Handler中将模版中需要的对象存在这个Map中,然后传递到view对应的ViewResolver中。

不同的ViewResolver会对这个Map中的对象有不同的处理方式;

velocity中将这个Map保存到VelocityContext中。
freemarker模板引擎来说将ModelMap包装成freemarker.template. TemplateHash Model
JSP中将每一个ModelMap中的元素分别设置到request.setAttribute(modelName,modelValue);

View设计

在springMVC中,view模块需要两个组件来支持: RequestToViewNameTranslator和ViewResolver

1.RequestToViewNameTranslator:主要支持用户自定义对viewName的解析,如将请求的ViewName加上前缀或者后缀,或者替换成特定的字符串等。

2.ViewResolver:主要是根据用户请求的viewName创建适合的模版引擎来渲染最终的页面,ViewResolver会根据viewName创建一个view对象,调用view对象的Void render方法渲染出页面。

本文系读书心得,参考自许令波先生的《深入分析Java Web技术内幕》——Spring MVC的工作机制和设计模式。感兴趣的同学可以拜读一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值