SpringMVC 探索(一)

基本介绍

Spring Wev MVC 是基于Sevlet和Spring的一个web框架,名字来源于它的源码
包(spring-webmvc),简称Spring MVC.

对于spring 5.0介绍了一个响应式web框架 Spring Wev Flux,命名来源于源码包名
称(spring-webflux)

核心控制器 DispatcherServlet

  • 简介
SpringMvc与其它web框架一样,是围绕中心Servlet设计的一个前端控制器模式,提供
了一个共享算法(dispatcherServlet)来处理请求,然而实际处理者确实通过配置的委
托组件,非常灵活。

DispatcherServlet 与其它 Servlet 一样,根据 Servlet 规范需要在 web.xml 
或 java 配置中声明,与此同时,DispatcherServlet 通过 Spring 配置来发现
它需要处理请求的委托组件,如:view resolution、exception handing等
  • 注册和初始化 DispatcherServlet
public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

此外,你也可以直接使用ServletContext API ,你也可以继承
AbstractAnnotationConfigDispatcherServletInitializer 重写它
具体的方法
  • Context Hierarchy(上下文层级关系)
DispatcherServlet 由于自己的配置需要一个 WebApplicationContext (是一个
ApplicationContext的继承类),WebApplicationContext与 ServletContxt 
和Servlet 建立了一个联系,它同时与ServletContext绑定在一起,对于应用来说,
可以通过 RequestContextUtils 的静态方法来查找他们需要的 
WebApplicationContext

Root WebApplicationContext 包含了一些典型的基础的 beans ,如他们需要在多
个servlet中共享的数据仓库、业务层,这些beans能够在子WebApplicationContext
中被重写、重新声明、继承,
  • 关系图如下(来自官网):

  • 配置 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 配置
<web-app>

    <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>

</web-app>

若应用上下文层级非必须的,则应用配置 根上下文 只有一个,或者让参数
contextConfigLocation 的 servlet 参数为空 
  • Special Bean 类型
BeanTypeExplanation
HandlerMapping匹配一个 request 与一系列interceptors去处理,匹配是基于一些规则的,主要通过HanderMapping的实现有关,主要实现类为RequestMappingHandlerMapping(支持@RequestMapping注解的方法)和 SimpleUrlHandlerMapping (主要维护URL路径中的显示注册处理)
HandlerAdapter帮助DispatcherServlet去请求一个匹配request的hander,不管它实际请求哪个hander,如请求一个注解controller,则需要解析这个注解,而HanderAdapter的目的则是隐藏DispatcherServlet的这些具体细节
HandlerExceptionResolver处理异常策略,尽可能匹配他们处理的异常,给Html错误视图,或者其它的目标
ViewResolver从处理请求中解析符合逻辑的字符串实际的视图名称,并提交给响应
LocaleResolver, LocaleContextResolver尽可能的使用当地的时间区域解析,用来提供一个国际化的视图
ThemeResolver解析你web程序的主题,提供一个个性化的布局
MultipartResolver解析多媒体请求(如:浏览器文件上传),帮助多媒体解析库
FlashMapManager存储和获取request中的请求参数FlashMap,可以用来将参数从一个请求传递到另一个请求,通常为 redirect

Wev Mvc Config

  • 简介
应用可以声明一些用来处理请求的一些基础特殊bean,该DispatcherServlet将会在
WebApplicationContext中查找这些beans,如果没有找到,则会回调在同级目录下
DispatcherServlet.propperties 文件中列出的默认类型 bean
  • Servlet Config
在Servlet 3.0+环境中,可以选择如下或与web.xml中结合来配置

import org.springframework.web.WebApplicationInitializer;

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}
  • WebApplicationInitializer 介绍
 WebApplicationInitializer 是 SpringMvc 提供的一个接口,用来确保你的实现
 类在Servlet 3 容器中能够被检测到,并自动初始化。有一个
 WebApplicationInitializer的抽象类为 AbstractDispatcherServletInitializer 
 用来简化 DispatcherServlet 的注册,通过重写具体的映射和配置文件的位置方法
  • 基于 Java 配置
 public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

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

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}
  • 基于 XML 的配置
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

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

上述均翻译自官方文档

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值