Spring MVC(一)

我只是大自然的搬运工! ————————————————————————————————————————————————————————————————————————————-@晗大大

Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中。正式名称“Spring Web MVC”来自其源模块(spring-webmvc)的名称,但它通常称为“Spring MVC”。

与Spring Web MVC并行,Spring Framework 5.0引入了一个反应式堆栈Web框架,其名称“Spring WebFlux”也基于其源模块(spring-webflux)。

DispatcherServlet
和许多其他web框架一样,Spring MVC是围绕前controller 模式设计的,其中一个重要的Servlet 为 DispatcherServlet,请求处理提供了一个共享算法,而实际工作则由可配置的委托组件执行。该模型灵活,支持多种工作流。
DispatcherServlet作为Servlet,都需要使用Java配置或web.xml根据Servlet规范声明和映射。反过来DispatcherServlet使用Spring配置来发现请求映射、view解析、异常处理等所需的委托组件。
以下Java配置示例注册并初始化DispatcherServlet,它由Servlet容器自动检测:
public class MyWebApplicationInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletCxt) {

    // 加载Spring web应用程序配置
    AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
    ac.register(AppConfig.class);
    ac.refresh();

    // 创建并注册DispatcherServlet
    DispatcherServlet servlet = new DispatcherServlet(ac);
    ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
    registration.setLoadOnStartup(1);
    registration.addMapping("/app/*");
}

}
以下web.xml配置示例注册并初始化DispatcherServlet:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-context.xml</param-value>
</context-param>

<servlet>
    <servlet-name>app</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>app</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>
Spring Boot遵循不同的初始化顺序。Spring Boot没有连接到Servlet容器的生命周期中,而是使用Spring配置来引导自身和嵌入式Servlet容器。在Spring配置中检测到过滤器和Servlet声明,并将其注册到Servlet容器中。

Context结构
DispatcherServlet需要WebApplicationContext(纯粹ApplicationContext的扩展)作为自己的配置。WebApplicationContext具有一个到ServletContext和Servlet的关联链接。它还绑定到ServletContext,这样应用程序可以在RequestContextUtils上使用静态方法,以便在需要访问WebApplicationContext时查找它。
对于许多应用程序来说,拥有一个WebApplicationContext是简单和足够的。也可以有一个上下文层次结构,其中一个root WebApplicationContext在多个DispatcherServlet(或其他Servlet)实例中共享,每个实例都有自己的子WebApplicationContext配置。
root WebApplicationContext通常包含基础设施bean,例如需要跨多个Servlet实例共享的数据存储库和业务服务。这些bean是有效继承的,可以在特定于Servlet的子WebApplicationContext中重写(即重新声明),该子WebApplicationContext通常包含给定Servlet的本地bean。下图显示了这种关系:

以下示例配置WebApplicationContext 层级结构:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { RootConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { App1Config.class };
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/app1/*" };
}

}
如果不需要应用程序上下文层次结构,则应用程序可以通过getRootConfigClasses()返回所有配置,并通过getServletConfigClasses()返回null。
下面的示例显示了web.xml的等效项:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/root-context.xml</param-value>
</context-param>

<servlet>
    <servlet-name>app1</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app1-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>app1</servlet-name>
    <url-pattern>/app1/*</url-pattern>
</servlet-mapping>
如果不需要应用程序上下文层次结构,则应用程序可以仅配置“root”上下文,并将contextConfigLocation Servlet参数保留为空。

欢迎关注我的其它发布渠道