Spring Web MVC 框架像其他web MVC框架和request-driven(请求驱动)一样,围绕着一个central Servlet(中心Servlet)设计,中心Servlet分发请求给Controller(控制器),并且提供一些其他有利于web应用开发的功能。然而,Spring里的DispatcherServlet可以做更多,它完全集成了Spring IOC容器,因此允许你使用Spring拥有的任意特征。
下面的图例为Spring MVC简单的处理流程。
1.用户发出请求。
2.前端控制器拦截用户请求,并将请求委托或者传递(调用页面控制器,处理器)。
3.页面控制器调用业务逻辑模型。
4.业务逻辑模型返回数据模型。
5.页面控制器将ModelAndView(一个对象)返回到前端控制器。
6.前端控制器调用其他构件渲染视图。
7.将视图返回到前端控制器(下面的图会展示)。
8.前端控制器返回视图,将视图呈现给用户。
上面是MVC请求流程,在此过程中SpringMVC会调用其他构件来处理一些模型(比如HandlerMapping处理映射关系,ViewResolver解析视图),Spring MVC处理请求的详细流程如下所示。
这个流程图和上面的流程图大同小异,只是更详细的展现了SpringMVC的请求流程。
前端控制器DispatcherServlet拦截用户发送的请求,然后调用HandlerMapping,根据HandlerMapping的返回值调用Controller(后端控制器),然后Controller调用业务逻辑对象,并将ModelAndView返回给前端控制器,前端控制器根据ViewResolver解析视图,将相应的视图呈现给用户。
在学习的深入之后,我们会更加详细的了解HandlerMapping和ViewResolver。
DispatcherServlet实际上是一个Servlet,(它继承了HttpServlet),因此需要在你的web应用里的web.xml
里面声明DispatcherServlet。你需要映射那些你想要DispatcherServlet处理的请求通过一个URL映射在同一个web.xml文件里。这是标准的Java EE Servlet配置。下面的代码是DispatcherServlet的声明和映射(配置)。
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
</web-app>
在上面的例子里,所有以/example开头的请求都会被以example命令(web.xml中servlet-name为example)的DispatcherServlet实例处理。在Servlet3.0+环境中,你也可以使用编程的方式配置Servlet容器,下面的代码和上面的web.xml是等价的。
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());
registration.setLoadOnStartup(1);
registration.addMapping("/example/*");
}
}
WebApplicationInitializer是Spring MVC提供的一个接口,它保证你在代码里的配置能够被检测并且自动用于初始化任意的Servlet3容器。这个接口的一个叫做AbstractDispatcherServletInitializer抽象实现类让注册
DispatcherServlet变得更加容易,仅仅通过指定它的servlet mapping。可以查看 Code-based Servlet container initialization (基于代码的Servlet容器初始化)获取更多详细信息。
上面的介绍仅仅是开始Spring Web MVC的第一步。你现在需要配置Spring Web MVC使用的各种bean。
over and above the DispatcherServlet itself(在DispatcherServlet本身之上)
在6.15节,“Additional Capabilities of the ApplicationContext”(ApplicationContext的额外功能)有详细介绍。Spring中的ApplicationContext 实例生命范围可以在整个Web MVC框架中。每一个DispatcherServlet都有它自己的WebApplicationContext。它继承根WebApplicationContext中已经定义的所有bean。这些继承的bean可以在servlet-specific(特定的Servlet)范围被重写。并且你也可以定义一个本地的新的scope-specific(特定范围的) bean给一个Servlet实例。
如下图所示,比较典型的Spring MVC Context层次图:
初始化一个DispatcherServlet时,Spring MVC会寻找一个在你当前web 应用下的WEB-INF文件夹下叫做[servlet-name]-servlet.xml的文件,并且在里面定义Bean。覆盖在全局范围内的定义的相同名字的任何bean.
思考一下下面的DispatcherServlet配置:
<web-app>
<servlet>
<servlet-name>golfing</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>golfing</servlet-name>
<url-pattern>/golfing/*</url-pattern>
</servlet-mapping>
</web-app>
在上面的Servlet配置中,你需要在你应用下的WEB-INF建一个叫做golfing-servlet.xml的文件。这个文件
包含你Spring Web MVC-specific 的容器(bean)。你可以改变这个配置文件的参数通过为Servlet初始化参数(看下面的细节)。
单例DispatcherServlet场景也可能只有一个根context
这可以通过设置一个空的 contextConfigLocation Servlet参数来配置,如下所示:
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
WebApplicationContext是ApplicationContext平台的扩展,它有一些对于web应用所必须的额外的特征。
它和ApplicationContext的不同之处在于能解决themes(主题)可以参考21.9节“Using themes”(使用主题)
并且她知道和哪一个Servlet有联系(通过和ServletContext链接)。WebApplicationContext被绑定在
ServletContext通过使用RequestContextUtils类上的静态方法,你如果想要使用它,总是可以找到
WebApplicationContext