Spring MVC 起步

218 阅读3分钟

跟踪Spring MVC的请求

所有请求的第一站是Spring的DispatcherServlet。与大多数java的web框架一样。Spring MVC所有请求都会通过一个前端控制器(front controller)Servlet。前端控制器是常用的web应用程序模式,在这里一个单例的servlet将请求委托给应用程序的其他组件来执行实际的处理,在spring mvc中,DispatcherServlet就是前端控制器。

DispatcherServlet的任务是将请求发送给Spring MVC控制器(controller)。控制器是一个用于处理请求的Spring组件。DispatcherServlet需要知道应该将请求发送给哪个控制器。所以DispatcherServlet会查询一个或多个处理器映射(handler mapping)来确定请求的下一站在哪里。处理器映射会根据请求所携带的URL信息来进行决策。

控制器处理结束之后将模型数据打包,并且标出用于渲染输出的视图名。他接下来会将请求连同模型和视图名发送给DispatcherServlet。

DispatcherServlet会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现,他可能是也可能不是JSP。

搭建Spring MVC

配置DispatcherServlet

DispatcherServlet是SpringMVC的核心。在这里请求会第一次接触到框架,他负责将请求路由到其他组件之中。

按照传统方式,像DispatcherServlet这样的Servlet会配置在web.xml文件中,这个文件会放到应用的WAR包里。当然,这是配置DispatcherServlet的方式之一。但是,借助于Servlet 3 规范和Spring 3.1的功能增强,这种方式已经不是唯一的方案了。

我们会使用Java将DispatcherServlet配置在Servlet容器中,而不会在使用web.xml文件。如下,展示了所需的Java类:

public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
    @Override
    protected String[] getServletMapping(){//将DispatcherServlet映射"/"
        return new String[]{"/"};
    }
    
    @Override
    protected Class<?>[] getRootConfigClasses(){
        return new Class<?>[] {RootConfig.class}
    }
    
    @Override
    protected Class<?>[] getServletConfigClasses(){//指定配置类
        return new Class<?>[]{WebConfig.class};
    }
}

我们只需要知道扩展AbstractAnnotationConfigDispatcherServletInitializer的任意类都会自动配置DispatcherServlet和Spring应用上下文,spring的应用上下文会位于应用程序的Servlet上下文中。

两个应用上下文之间的故事

当DispatcherServlet启动的时候,他会创建Spring应用上下文,并加载配置文件或配置类中声明的bean。

但是在Spring Web应用中,通常还会有另一个应用上下文。另外这个应用上下文是由ContextLoaderListener创建的。

我们希望DIspatcherServlet加载包含Web组建的bean,如控制器,视图解析器以及处理器映射,而ContextLoaderLisenner要加载应用中的其他bean。这些bean通常是驱动应用后端的中间层和数据层组件

实际上AbstractAnnotationConfigDispatcherServletInitializer会同时创建DispatcherServlet和ContextLoaderListener。GetServletConfigClasses()方法返回的带有@Configuration注解的类将会用来定义DispatcherServlet应用上下文中的bean。getRootConfigClasses()方法返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean。

在本例中,根配置定义在RootConfig中,DispatcherServlet的配置声明在WebConfig中。

需要注意的是,通过AbstractAnnotationConfigDispatcherServletInitializer来配置DispatcherServlet是传统web.xml方式的代替方案。如果按照这种方式配置DispatcherServlet,而不是使用web.xml的话,那唯一问题在于它只能部署到支持servlet 3.0的服务器中才能正常工作,如tomcat7或者更高版本。

启用Spring MVC

我们有多种方式来配置DispatcherServlet,与之类似,启用Spring MVC的方法也不止一种。以前,Spring 是使用XML进行配置的,你可以使用mvc:annotation-driven启用注解驱动的Spring MVC。

现在我们基于java进行配置;

@Configration
@EnableWebMvc
@ComponenScan("cn.demo")
public class WebConfig extends WebMvcConfigurerAdapter{
    //配置jsp视图解析器
    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("WEB-INF/views/");
    resolver.setSuffix(".jsp");
    resolver.setExposeContextBeanAsAttributes(true);
    }
    //配置静态资源的处理
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
        configurer.enable();
    }
}

RootConfig

@Configuration
@ComponentScan(basePackages={"spittr"},@Filter(type=FilterType.ANNOTATION,value=EnableWebMvc.class))
public class RootConfig{
    
}