Spring boot 增加拦截器的时候用EnableWebMvc注解导致无法加载静态资源

参考资料:
Av65117012,P30:30 通过源码分析不能加载资源问题(Av65117012,P30).mp4

下面配置拦截器SessionInterceptor的代码,运行后静态资源不能记载,因为加了@EnableWebMvc注解,下面来探究下为什么?

@Configuration
@EnableWebMvc
public class Webconfig implements WebMvcConfigurer {

    @Autowired
    SessionInterceptor sessionInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sessionInterceptor).addPathPatterns("/**");
    }
}

我们首先点进去WebMvcConfigurer,找到它的一个实现类WebMvcAutoConfigurationAdapter,看名字大概可以猜到如果没有配置,Spring boot会在这里面自动进行配置,里面有个方法addResourceHandlers可以添加静态资源路径,包括static这些,那为什么没有执行呢?注意到类上面有个@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)的注解,大概意思是说,如果容器中没有WebMvcConfigurationSupport这个类的对象才会创建WebMvcAutoConfigurationAdapter 的相关对象,接下来我们来看看哪里创建了。

public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {

         @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
                return;
            }
            Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
            CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
            if (!registry.hasMappingForPattern("/webjars/**")) {
                customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                        .addResourceLocations("classpath:/META-INF/resources/webjars/")
                        .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }
            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
            if (!registry.hasMappingForPattern(staticPathPattern)) {
                customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                        .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                        .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }
        }
}

点进去注解@EnableWebMvc看到有下面的一行引入了类DelegatingWebMvcConfiguration,它是继承自WebMvcConfigurationSupport,所以就可以承接我们上面的思路,没有了WebMvcAutoConfigurationAdapter,也不会自动配置静态资源路径了。
下面是DelegatingWebMvcConfiguration增加静态资源的方法,调用了它的所有的configurers的addResourceHandlers

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        this.configurers.addResourceHandlers(registry);
    }

configurers是怎么来的呢?看到注解Autowired,下面的代码会将容器中所有的WebMvcConfigurer的对象放到configurers中去。

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

而我们前面编写的Webconfig就是一个WebMvcConfigurer。

public class Webconfig implements WebMvcConfigurer

综上,要解决上面的问题:
1、去掉EnableWebMvc注解
2、在我们自己定义的类Webconfig中覆盖方法addResourceHandlers加入静态资源路径。

你可能感兴趣的:(Spring boot 增加拦截器的时候用EnableWebMvc注解导致无法加载静态资源)