Spring MVC 初始化和流程

来源:互联网 发布:二维码扫描价格软件 编辑:程序博客网 时间:2024/06/01 14:36

Spring MVC 组件与流程

  • 概念
    Spring MVC的核心在于其流程,这是使用Spring MVC框架的基础,Spring MVC是一种基于Servlet的技术,它提供了核心控制器DispatcherServlet和相关的组件,并制定了松散的结构,以适应各种灵活的需要。
  • 原理
    首先,Spring MVC框架是围绕DispatcherServlet而工作的,所以这个类是其最为重要的类。因为它可以拦截HTTP发送过来的请求,在servlet初始化(调用init方法)时,Spring MVC会根据配置,获取配置信息,从而得到统一资源标识符和处理器(Handler)质检的映射关系(HandlerMapping),为了更加灵活和增强功能,Spring MVC还会给处理器加入拦截器,所以还可以在处理器执行前后加入自己的代码,这样就构成了一个处理器的执行链,并根据上下文初始化试图解析器等内容,当处理器返回的时候就可以通过视图解析器定位视图,然后将数据模型渲染到视图中,用来响应用户的请求了。
  • 流程1
    当一个请求到来时,DispatcherServlet首先通过请求和事先解析好的HandlerMapping配置,找到对应的处理器(Handler),这样就准备开始运行处理器和拦截器组成的执行链,
    而运行处理器需要有一个对应的环境,这样它就有了一个处理器的适配器,通过这个适配器就能运行对应的处理器及其拦截器,这里的处理器包含了控制器的内容和其他增强的功能,在处理器返回模型和视图给DispacherServlet后,DispacherServlet就会把对应的视图信息传递给视图解析器。
  • 流程2
    当Spring MVC启动的时候就会去解析 XXXController的注解,然后生成对应的URI和请求的映射关系,并注册对应的方法。当请求来到的时候,首先根据URI找到对应的HandlerMapping,然后组织为一个执行链,通过请求类型找到RequestMappingHandlerAdapter,它的实例是在DispatcherServlet初始化的时候进行创建的。然后通过它去执行HandlerExecutionChain的内容,最终在XXXController的方法中将视图返回给DispatchServlet。

注解解释

  • @Controller:代表该类是一个控制器,Spring MVC描述的时候就会把它作为控制器加载进来。
  • @RequestMapping:指定了对应的请求的URI,Spring MVC在初始化的时候就会将这些信息解析,存封起来,于是便有了HandlerMapping。当发生请求时,Spring MVC就会去使用这些信息去找到对应的控制器提供服务。

单词解释:
ContextLoaderListener:
实现了接口ServletContextListener,ServletContextListener的作用是可以在整个Web工程前后加入自定义代码,所以可以在Web工程初始化之前,它先完成Spring Ioc容器的初始化,也可以在Web工程关闭之时完成Spring Ioc容器的资源进行释放。

Spring MVC 初始化
整个Spring MVC初始化,配置了DispatcherServlet和ContextLoaderListener,所以Spring MVC初始化会涉及两个上下文的初始化及Spring Ioc容器上下文和映射请求上下文。

  • 初始化Spring Ioc上下文
    Java Web容器为其生命周期中提供ServletContextListener接口,这个接口可以在Web容器初始化和生命周期中执行一定的逻辑,就是说,通过它可以使得在DispatcherServlet初始化前就可以完成Spring Ioc容器的初始化,也可以在结束期完成对Spring Ioc容器的销毁,只要实现ServletContextListener接口的方法就可以了。
  • 初始化映射请求上下文
    映射请求上下文是通过DispatcherServlet初始化的,它和普通的Servlet也是一样的,可以根据自己的需要配置它在启动时初始化,或者等待用户第一次请求的时候进行初始化。如果在Web工程中并没有注册ContextLoaderListener,这个时候DispatcherServlet就会在其初始化的时候进行对Spring Ioc容器的初始化。
    什么时候初始化DispatcherServlet?
    可以让DispatcherServlet在服务器启动期间完成Spring Ioc容器的初始化,我们可以在Web容器刚启动的时候,也可以在Web容器载入DispatcherServlet的时候进行初始化。建议在Web容器刚开始的时候进行初始化,因为在整个Web的初始化中,不只是DispatcherServlet需要Spring Ioc的资源,其他的组件可能也需要。

Spring MVC 核心组件
按照加载顺序:
1. MultipartResolver:文件解析器。用于支持服务器的文件上传。
2. LocaleResolver:国际化解析器,可以提供国际化的功能。
3. ThemeResolver:主题解析器,类似于软件皮肤的转换功能。
4. HandlerMapping:Spring MVC中十分重要的内容,它会包装用户提供一个控制器的方法和对它的一些拦截器,通过调用它就能够运行控制器。
5. handlerAdapter:处理适配器,因为处理器会在不同的上下文中运行,所以Spring MVC会先找到合适的适配器,然后运行处理器服务方法。
6. HandlerExceptionResolver:处理器异常解析器,处理器有可能产生异常,如果产生异常,则可以通过异常解析器来处理它。比如出现异常后跳转到统一的异常处理页面。
7. RequestToViewNameTranslator:视图逻辑名称转换器,有时候在控制器中返回一个视图的名称,通过它可以找到实际的视图。当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名。
8. ViewResolver:视图解析器,当控制器返回后,通过试图解析器会把逻辑视图名称进行解析,然后定位实际视图。

使用注解配置方式初始化
由于在Servlet 3.0之后的规范允许取消web.xml配置,只使用注解方式便可以了,所以在Servlet 3.1之后的版本也提供了注解方式的配置。只要继承一个类 AbstractAnnotationConfigDispatcherServletInitializer,然后实现它所定义的方法。
只要继承它就能实现DispatcherServlet映射关系和Spring Ioc容器的初始化工作。
配置类代如下:

package com.bob.analyst.admin.aop;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{    //Spring Ioc 容器配置    @Override    protected Class<?>[] getRootConfigClasses() {        //可以返回Spring 的Java 配置文件数组        return new Class<?>[] {};    }    //DispatcherServlet的URI映射关系配置    @Override    protected Class<?>[] getServletConfigClasses() {        //可以返回Spring 的Java配之间数据        return new Class<?>[]{};    }    //DispatcherServlet 拦截内容    @Override    protected String[] getServletMappings() {        return new String[]{"*.do"};    }}

备注:

  • 如果getRootConfigClasses方法返回为空,就不加载自定义的Bean到Spring Ioc容器中,而getServletConfigClasses加载了WebConfig,则它就是一个URI和控制器的映射关系类。由此产生Web请求上下文。
  • Servlet 3.0之后的版本允许动态加载 Servlect,只是按照规范需要实现ServletContainerInitializer接口而已。于是Spring MVC框架自己的包内实现了一个类,它就是SpringServletContainerInitializer,它实现了ServletContainerInitializer接口,这样就能通过它去加载开发者提供的配置类了。

加载类如下:

package com.bob.analyst.admin.aop;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration//定义扫描的包,加载控制器@ComponentScan("com.*")//启用Spring Web MVC@EnableWebMvcpublic class WebConfig {    /**     * 创建视图解析器     * @return 视图解析器     */    @Bean(name="viewResolver")    public InternalResourceViewResolver ViewResolverinitViewResolver(){        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();        viewResolver.setPrefix("/WEB-INF/jsp/");        viewResolver.setSuffix(".jsp");        return viewResolver;    }}

备注:
@EnableWebMvc 注解代表它启动Spring MVC框架的配置。