Spring MVC的总体设计
要使用Sping MVC,只需要在 web.xml 中配置一个 DispatcherServlet :dispatcherServletorg.springframework.web.servlet.DispatcherServletdispatcherServlet/*再定义一个 dispatcherServlet
要使用Sping MVC,只需要在 web.xml 中配置一个 DispatcherServlet :
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
再定义一个 dispatcherServlet-servlet.xml 配置文件:
<beans>
<!-- 定义Mapping -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandler-Mapping">
<property name="mappings">
<props>
<prop key="demo.html">demo</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref bean="interceptor" />
</list>
</property>
</bean>
<bean id="interceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
<!-- 定义View -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResource-ViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.InternalResource-View</value>
</property>
</bean>
<!-- 定义Control -->
<bean id="demo" class="com.yb.mvc.demo">
<property name="viewPage">
<value>/demo.html</valus>
</property>
</bean>
</beans>
这样一个简单的基于Spring MVC 的应用就创建完成了。
Spring MVC 的使用非常简单,如上述代码所示我们只要扩展一个路径映射关系;定义一个视图解析器;在定义一个业务逻辑的处理流程规划,Spring MVC 就能够帮我们完成所有的MVC功能了。
DispatcherServlet 类相关结构图:
initMultipartResolver:初始化 MultipartResolver ,用于处理文件上传服务,如果有文件上传,那么会将当前的 HttpServletRequest包装成 DefaultMultipartHttpServletRequest ,并且将每个上传的内容封装成 CommonsMultipartFile 对象。
initLocaleResolver:用于处理应用的国际化问题,通过解析请求的 Locale 和设置响应的 Locale 来控制应用中的字符编码问题。
initThemeResolver:用于定义一个主题,例如,可以根据用户的喜好来设置用户访问页面的样式,可以将这个样式作为一个 Theme Name 保存,保存在用于请求来的Cookie 中或者保存在服务端的 Session 中,以后每次请求根据这个 Theme Name 返回特定的内容。
initHandlerMappings:用于定义用户设置的请求映射关系,例如,前面示例中的 SimpleUrlHandlerMapping 把用于用户请求的 URL 映射成一个个 Handler 实例。对 HandlerMapping 必须定义,如果没有定义,将获取 DispatcherServlet.properties 文件中默认的两个 HandlerMapping,分别是 BeanNameUrlHandlerMapping 和DefaultAnnotationHandlerMapping。
initHandlerAdapters:用于根据 Handler 的类型定义不同的处理规则,例如,定义 SimpleControllerHandlerAdapter 处理所有的 Controller 实例对象,在 HandlerMapping 中将 URL 映射成一个 Controller 实例,那么 Spring MVC在解析时 SimpleControllerHandlerAdapter 就会调用这个 Controller 实例。同样对HandlerAdapters 也必须定义,如果没有定义,将获取 DispatcherServlet.properties 文件中默认的4个 HandlerAdapters,分别是 HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、ThrowawayControllerHandlerAdapter和AnnotationMethodHandlerAdapter。
initHandlerExceptionResolvers:当 Handler 处理出错时,会通过这个 Handler 来统一处理,默认的实现类是 SimpleMappingExceptionResolver,将错误日志记录在log文件中,并且转到默认的错误页面。
initRequestToViewNameTranslator:将指定的 ViewName 按照定义的 RequestToViewNameTranslator 替换成想要的格式,如加上前缀或者后缀等。
initViewResolvers:用于将 view 解析成页面,在 viewResolvers 中可以设置多个解析策略,如可以根据 JSP 来解析,或者按照 Velocity 模板解析。默认的解析策略是InternalResourceViewResolver,按照 JSP 页面来解析。
从上面的初始化策略可以看出,在一个请求中可能需要我们来扩展的地方都定义了扩展点,只要实现相关的接口类,并创建一个 Spring Bean 就能扩展 Spring MVC 框架。
在 Spring MVC 框架中,有3个组件是用户必须要定义和扩展的:定义 URL 映射规则、实现业务逻辑的 Handler 实例对象、渲染模板资源。而连接 Handler 实例对象和模板渲染的纽带就是 Model 模型了。
下面看看 DispatcherServlet 在启动时都做了哪些事情?
HttpServlet 初始化调用了 HttpServletBean 的init() 方法,该方法的作用是获取 Servlet 中的 init 参数,并创建一个 BeanWrapper 对象,然后由子类处真正执行 BeanWrapper 的初始化工作。但是 HttpServletBean 的子类 FrameworkServlet 和 DispatcherServlet 都没有覆盖其 initBeanWrapper(bw) 方法,所以创建的 BeanWrapper 对象没有任何作用,Spring 容器也不是通过 BeanWrapper 来创建的。
Spring 容器的创建是在 FrameworkServlet 的 initServletBean() 方法中完成的,这个方法会创建 WebApplicationContext 对象,并调用其 refresh() 方法来完成配置文件的加载,配置文件的加载同样先是查找 Servlet 的init-param 参数中设置的路径,如果没有,会根据namespace+Servlet 的名称来查找 XML 文件。Spring 容器在加载时会调用 DispatcherServlet 的 initStrategies 方法来完成在 DispatcherServlet 中定义的初始化工作。在 initStrategies 方法中会初始化 Spring MVC 框架需要的8个组件,这8个组件对应的8个 Bean 对象都保存在 DispatcherServlet 类中。
Spring MVC初始化时序图如图所示:
这时 DispatcherServlet 已经初始化完成,Spring MVC 也已经初始化完成,可以接受HTTP请求了。
--《深入分析Java Web技术内幕修订版》 Page 365-Page 369
更多推荐
所有评论(0)