Spring MVC Java配置梳理

本文详细梳理了Spring MVC的处理流程,包括DispatcherServlet的作用、Controller的交互,以及Servlet 3规范下的Java配置方式。通过创建配置类,实现了Servlet容器的Java配置,探讨了ContextLoaderListener和DispatcherServlet上下文的区别。同时,文章还深入讲解了MVC上下文配置,如视图解析器、静态资源处理以及WebMvcConfigurerAdapter的主要方法,帮助读者全面理解Spring MVC的配置细节。
摘要由CSDN通过智能技术生成

Spring MVC处理流程

  1. DispatcherServlet收到用户请求
  2. DS调用处理映射器来找到具体Controller
  3. DS将请求发送给具体Controller
  4. Controller返回ViewAndModel给DS
  5. DS通过视图解析器解析出具体视图位置
  6. DS用Model来渲染视图
  7. 被渲染的视图最终响应给用户

Servelet 3规范下的Spring MVC配置

创建继承AbstractAnnotationConfigDispatcherServletInitializer的配置类,通过覆盖该类方法来配置Servlet容器中的类容。

  1. getServletMappings 配置DispatcherServlet映射
  2. getRootConfigClasses 配置Root上下文配置类
  3. getServletConfigClasses 配置MVC上下文配置类

注意:

在Servlet 3规范下我们可以不用配置web.xml文件,所有配置全部在java中完成。
具体实现原理是:

Servlet 3容器会在类路径下查找实现javax.servlet.ServletContainerInitializer接口的类,如果发现的话,就会用他来配置Servlet容器。

Spring提供了实现该接口的SpringServletContainerInitializer类,此类又会查找实现WebApplicationInitializer接口的类来完成配置。

Spring为WebApplicationInitializer提供了一个便利的实现类AbstractAnnotationConfigDispatcherServletInitializer

所以但我们提供一个继承AbstractAnnotationConfigDispatcherServletInitializer的配置类,SpringServletContainerInitializer将会发现它,并完成所有的Servlet容器的配置。

两个上下文的区别

  1. ContextLoaderListener创建的上下文用来配置后端的中间件和数据层
  2. DispatcherServlet启动时候创建的上下文用来配置MVC的组件,控制器,视图解析器等

MVC上下文配置类

基于java-based方式的spring mvc配置,需要创建一个配置类并实现WebMvcConfigurer 接口,WebMvcConfigurerAdapter 抽象类是对WebMvcConfigurer 接口的简单抽象(增加了一些默认实现),所以上面配置代码选择直接继承WebMvcConfigurerAdapter 。然后根据项目的需要实现接口中特定的方法,最后要注意的是,要在配置类上标注@EnableWebMvc

但是这是远不够的,需要丰富更多的配置。

视图解析器配置示例

@Bean
  public ViewResolver viewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    return resolver;
  }

该示例配置了一个InternalResourceViewResolver解析器,通过根据逻辑视图名称,以及自定义的前后缀名来定义具体视图位置。

静态资源处理配置

@Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
  }

MVC配置类需要继承WebMvcConfigurerAdapter类,通过重写父方法来完善MVC配置。

WebMvcConfigurerAdapter一些主要方法

  1. configureViewResolvers(ViewResolverRegistry registry);
    通过调用ViewResolverRegistry的方法来进行ViewResolvers的配置。

ViewResolverRegistry常用方法有:

->public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) 用来注册InternalResourceViewResolver ,作用类似与直接在上下文中装配一个InternalResourceViewResolver的Bean。

->public void beanName() 用来注册BeanNameViewResolver,该解析器视图名称解析成对应的bean。什么意思呢?假如返回的视图名称是example,它会到spring容器中找有没有一个叫example的bean,并且这个bean是View.class类型的?如果有,返回这个bean。

->public void viewResolver(ViewResolver viewResolver)用来注册各种其他的,或者是自定义的视图解析器。

  1. addViewControllers(ViewControllerRegistry registry)
    此方法可以很方便的实现一个请求到视图的映射,而无需书写controller,例如:
@Override  
    public void addViewControllers(ViewControllerRegistry registry){  
        registry.addViewController("/login").setViewName("login");  
    } 
  1. addResourceHandlers(ResourceHandlerRegistry registry)
    此方法用来专门注册一个Handler,来处理静态资源的,例如:图片,js,css等。举例:
@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resource/**").addResourceLocations("/WEB-INF/static/");
    }

当你请求http://localhost:8083/resource/1.png时,会把/WEB-INF/static/1.png返回。注意:这里的静态资源是放置在WEB-INF目录下的。

  1. configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
@Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

此时会注册一个默认的Handler:DefaultServletHttpRequestHandler,这个Handler也是用来处理静态文件的,它会尝试映射/*。当DispatcherServelt映射/时(/ 和/* 是有区别的),并且没有找到合适的Handler来处理请求时,就会交给DefaultServletHttpRequestHandler 来处理。注意:这里的静态资源是放置在web根目录下,而非WEB-INF 下。

简单举个例子,例如在webroot目录下有一个图片1.png。由于DispatcherServlet配置了映射路径是:/ ,它几乎把所有的请求都拦截了,从而导致1.png 访问不到,这时注册一个DefaultServletHttpRequestHandler 就可以解决这个问题。其实可以理解为DispatcherServlet破坏了Servlet的一个特性(根目录下的文件可以直接访问),DefaultServletHttpRequestHandler是帮助回归这个特性的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值