SpringBoot学习-SpringMVC配置

SpringMVC自动配置

一:添加到容器(自动配置)

SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component),如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(如ViewResolver),则将用户配置的和SpringBoot默认的组合起来。

二:扩展SpringMVC

Spring5.0之前(WebMvcConfigurerAdapter过时)

编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型,不能标注@EnableWebMvc

既保留了所有的自动配置,也能用我们扩展的配置

1
2
3
4
5
6
7
8
9
//使用WebMvcConfigurer可以扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器发送 /ligangit 请求来到成功页面
registry.addViewController("/ligangit").setViewName("success");
}
}

Spring5.0之后

  1. 方法一:实现WebMvcConfigurer接口(推荐)

    编写一个配置类(@Configuration),实现WebMvcConfigurer接口,不能标注@EnableWebMvc

    既保留了所有的自动配置,也能用我们扩展的配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //使用WebMvcConfigurer可以扩展SpringMVC的功能
    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    // 浏览器发送 /ligangit 请求来到成功页面
    registry.addViewController("/ligangit").setViewName("success");
    }
    }
  2. 方法二:继承WebMvcConfigurationSupport类

    编写一个配置类(@Configuration),是WebMvcConfigurationSupport类型,不能标注@EnableWebMvc

    既保留了所有的自动配置,也能用我们扩展的配置;

    相当于覆盖了@EnableAutoConfiguration里的所有方法,每个方法都需要重写,比如,若不实现方法addResourceHandlers(),则会导致静态资源无法访问,实现的方法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //使用WebMvcConfigurer可以扩展SpringMVC的功能
    @Configuration
    public class MyMvcConfig extends WebMvcConfigurationSupport{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    // 浏览器发送 /ligangit 请求来到成功页面
    registry.addViewController("/ligangit").setViewName("success");
    }

    // 重写addResourceHandlers方法,若不实现方法addResourceHandlers(),则会导致静态资源无法访问
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**")
    .addResourceLocations("classpath:/META-INF/resources/")
    .addResourceLocations("classpath:/resources/")
    .addResourceLocations("classpath:/static/")
    .addResourceLocations("classpath:/public/");
    super.addResourceHandlers(registry);
    }
    }

原理

  1. WebMvcAutoConfiguration是SpringMVC的自动配置类

  2. 在做其他自动配置时会导入@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})

    • EnableWebMvcConfiguration类继承了DelegatingWebMvcConfiguration类

      1
      2
      3
      4
      @Configuration(
      proxyBeanMethods = false
      )
      public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    • DelegatingWebMvcConfiguration类中有个setConfigurers()方法,从容器中获取所有的WebMvcConfigurer

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      @Configuration(
      proxyBeanMethods = false
      )
      public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
      private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

      public DelegatingWebMvcConfiguration() {
      }

      @Autowired(
      required = false
      )
      public void setConfigurers(List<WebMvcConfigurer> configurers) {
      if (!CollectionUtils.isEmpty(configurers)) {
      this.configurers.addWebMvcConfigurers(configurers);
      }

      }
    • DelegatingWebMvcConfiguration类中调用WebMvcConfigurerComposite类中的方法,实现获取的所有WebMvcConfigurer中的方法(即将WebMvcConfigurer中的方法都执行一遍)

      将所有的WebMvcConfigurer相关配置都来一起调用

      WebMvcConfigurerComposite类中的一个参考实现:

      1
      2
      3
      4
      5
      6
      7
      public void addViewControllers(ViewControllerRegistry registry) {
      Iterator var2 = this.delegates.iterator();
      while(var2.hasNext()) {
      WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
      delegate.addViewControllers(registry);
      }
      }
  3. 容器中所有的WebMvcConfigurer都会一起起作用

  4. 我们的配置类也会被调用

效果

SpringMVC的自动配置和我们的扩展配置都会起作用。

三:全面接管SpringMVC(不推荐)

实现

SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配;所有的SpringMVC的自动配置都失效了

我们需要在配置类中添加@EnableWebMvc

1
2
3
4
5
6
7
8
9
10
//使用WebMvcConfigurer可以扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器发送 /ligangit 请求来到成功页面
registry.addViewController("/ligangit").setViewName("success");
}
}

原理

为什么@EnableWebMvc自动配置就失效了?

  1. @EnableWebMvc的核心:@Import({DelegatingWebMvcConfiguration.class})

    1
    2
    3
    4
    5
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @Documented
    @Import({DelegatingWebMvcConfiguration.class})
    public @interface EnableWebMvc {
  2. DelegatingWebMvcConfiguration类:

    1
    2
    3
    4
    @Configuration(
    proxyBeanMethods = false
    )
    public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
  3. 查看WebMvcAutoConfiguration类(SpringMVC自动配置类)

    容器中没有这个组件的时候,这个自动配置类才生效
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Configuration(
    proxyBeanMethods = false
    )
    @ConditionalOnWebApplication(
    type = Type.SERVLET
    )
    @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
    //容器中没有这个组件的时候,这个自动配置类才生效
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
    @AutoConfigureOrder(-2147483638)
    @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
    public class WebMvcAutoConfiguration {
  4. @EnableWebMvc将WebMvcConfigurationSupport组件导入进来

  5. 导入的WebMvcConfigurationSupport只是最基本的功能;

如何修改SpringBoot的默认配置

  1. SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component),如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(如ViewResolver),则将用户配置的和SpringBoot默认的组合起来。
  2. 在SpringBoot中会有非常多的xxxConfiger帮助我们进行扩展配置。
  3. 在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置

最后更新: 2020年07月30日 15:13

原始链接: http://ligangit.com/2020/07/27/SpringBoot学习-SpringMVC配置/

× 请我吃糖~
打赏二维码