Spring学习笔记之Spring MVC的工作机制

目前市场上主流的MVC框架是Spring MVC和Struts。前面我们介绍了Spring框架的设计理念,这一篇我们介绍Spring MVC。Spring MVC与Spring框架是无缝结合的。本文基于Spring2.3.6版本介绍Spring MVC 的总体设计,然后再介绍其对应的M、V、 C分别是什么。

Spring MVC的总体设计

我们知道,要使用Spring MVC很简单,只需要在web.xml中配置一个Servlet即DispatcherServlet:

<servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        <url-pattern>/*url-pattern>
    servlet-mapping>

然后再定义一个dispatcherServlet-servlet.xml配置文件,就可以了。

<beans> 
         
    <bean id="urlMapping" 
class="org.springframework.web.servlet.handler.  
            SimpleUrlHandlerMapping"> 
        <property name="mappings"> 
            <props> 
                <prop key="helloWorld.do">helloWorldControllerprop> 
            props> 
        property> 
bean> 
 
    <bean id="viewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
        <property name="viewClass"> 
            <value>org.springframework.web.servlet.view.InternalResourceViewvalue> 
        property>   
bean> 
 
    <bean id="helloWorldController" class="com.myHelloWorld.action.HelloWorldController"> 
        <property name="helloWorld"> 
            <value>HelloWorldvalue> 
        property> 
        <property name="viewPage"> 
            <value>/jsp/helloWorld.jspvalue> 
        property> 
    bean> 
beans> 

下面是DispatcherServlet的类相关结构图:
Spring学习笔记之Spring MVC的工作机制_第1张图片
DispatcherServlet类继承了HttpServlet,在Servlet的init方法调用时DispatcherServlet执行Spring MVC的初始化工作。DispatcherServlet初始化做什么?可以在其initStrategies方法中知道:

protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
    }

主要做8件事(在后面的版本又新加了一个initFlashMapManager(context);)

  • initMultipartResolver:初始化MultipartResolver,用于处理文件上传服务,如果有文件上传,那么会将当前的HttpServletRequest包装成DefaultMultipartHttpServletRequest,并且将每个上传的内容封装成CommonsMultipartFile对象。
  • initLocaleResolver:用于处理应用的国际化问题,通过解析请求的Locale和设置响应的Locale来控制应用中的字节编码问题。
  • initThemeResolver:用于定义一个主题。
  • initHandlerMappings:用于定义用户的请求映射关系。HandlerMapping必须定义,如果没有定义,将获取DispatcherServlet.properties文件中默认的两个HandlerMapping,分别是BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping。
  • initHandlerAdapters:用于根据Handle的类型定义不同的处理规则。同样对HandlerAdapter也必须定义,如果没有定义,将获取DispatcherServlet.properties文件中默认的4个HandlerAdapter,分别是HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter和ThrowawayControllerHandleAdapter(后面的版本中没有这一个)
  • initHandlerExceptionResolvers:当Handler处理出错时,会通过这个Handler来统一处理,默认的实现类是SimpleMappingExceptionResolver,将错误日志记录在log文件中,并且转到默认的错误页面。
  • initRequestToViewNameTranslator:将指定的ViewName按照定义的RequestToViewNameTranslator替换成想要的格式,如加上前缀和后缀等。
  • initViewResolvers:用于将View解析成页面。默认的解析策略是InternalResourceViewResolver,按照JSP页面来解析。

从上面的初始化策略可以看出,在一个请求中可能需要我们来扩展的地方都定义了扩展点。只要试下相应的接口类,并创建一个Spring Bean就能扩展Spring MVC框架。
Spring学习笔记之Spring MVC的工作机制_第2张图片
在Spring MVC框架中,有3个组件是用户必须要定义和扩展的:定义URL映射规则、实现业务逻辑的Handle实例对象,渲染模板资源。
Spring容器的创建是在FrameworkServletinitServletBean()方法中完成的,这个方法会创建WebApplicationContext对象,并调用其refresh()方法来完成配置文件的加载,配置文件的加载同样是先查找Servlet的init-param参数中设置的路径,如果没有,会根据namespace+Servlet的名称来查找XML文件。Spring容器在加载时会调用DispatcherServlet的initStrategies方法来完成在DispatcherServlet中定义的初始化工作。在initStrategies方法中会初始化Spring MVC框架需要的8个组件,这8个组件对应的8个Bean对象都保存在DispatcherServlet类中。

Control

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

Model

ModleAndView对象是连接业务逻辑层与View展现层的桥梁,对于Spring MVC来说就是连接Handler和View的桥梁。ModelAndView 会持有一个ModelMap对象和一个View对象或者View的名称。ModelMap其实就是个Map。

View

对Spring MVC的View来说,它又两个组件支持,分别是RequestViewNameTranslator和ViewResolver。RequestViewNameTranslator支持用户子弟你对ViewName的解析,如将请求的ViewName加上前缀或者后缀,或者替换成特定的字符串等。而ViewResolver用于根据用户请求的ViewName创建合适的模板引擎来渲染最终的页面,ViewResolver会根据ViewName创建一个View对象,调用View对象的void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception方法渲染页面。

由于版本更新的问题,文章中某些地方可能和现在的版本不一样,但总体的框架是不会变太多的,本文的用意也是通过对Spring MVC框架有一个总体的把握,从而让我们对后面Spring的学习可以有一个清晰的脉络。

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

你可能感兴趣的:(Spring学习笔记)