源码分析@EnableWebMvc导致静态链接无法加载

在做项目的时候,给拦截器如果加上@EnableWebMvc注解会导致静态的资源加载不进来,而使用@Configuration就不会出现这个问题,虽然我没遇到,但是我看到了这个问题,就顺便把这个问题记录下来,并从源码中分析一下这个注解。

@Configuration
@EnableWebMvc
public class webConfig implements WebMvcConfigurer {

    @Autowired
    private SessionInterceptor sessionInterceptor;

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

进入EnableWebMvc的源码如下,

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

可以很明显的发现**@Import(DelegatingWebMvcConfiguration.class)**这行代码,这不就是WebMvcConfigurationSupport的子类么,是专门来配置Mvc的一些配置,并加载各种WebMvc的配置。


@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

    //用来加载所有的WebMvcConfiguer配置,这也就是说我们也可以自定义WebMvcConfiguer,它会自动的搜索并加载。
    //AutoWired注解后边默认required=true,表示的是要注入的这些必须存在不然就会报错,当选为false的时候,如果没有就直接跳过了
	@Autowired(required = false)
	public void setConfigurers(List configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}

   //配置路径匹配
	@Override
	protected void configurePathMatch(PathMatchConfigurer configurer) {
		this.configurers.configurePathMatch(configurer);
	}

   //是一个内容协商配置
   	@Override
	protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		this.configurers.configureContentNegotiation(configurer);
	}
   //异步支持配置
	@Override
	protected void configureAsyncSupport(AsyncSupportConfigurer configurer) {
		this.configurers.configureAsyncSupport(configurer);
	}
    //也是用来处理静态资源文件的,WEB-INF
	@Override
	protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		this.configurers.configureDefaultServletHandling(configurer);
	}

    //格式转换器,比如我们的输入输出格式等 
	@Override
	protected void addFormatters(FormatterRegistry registry) {
		this.configurers.addFormatters(registry);
	}
   //拦截器
	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		this.configurers.addInterceptors(registry);
	}
    //添加资源映射
	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		this.configurers.addResourceHandlers(registry);
	}
    //用来添加Cros跨域映射
	@Override
	protected void addCorsMappings(CorsRegistry registry) {
		this.configurers.addCorsMappings(registry);
	}
   //给controller的映射适配资源文件,就和放在Template的html自动配置了解析一样
	@Override
	protected void addViewControllers(ViewControllerRegistry registry) {
		this.configurers.addViewControllers(registry);
	}
   //增加视图解析器,就可我们配置的jsp的前缀后缀
	@Override
	protected void configureViewResolvers(ViewResolverRegistry registry) {
		this.configurers.configureViewResolvers(registry);
	}

    //参数类型解析 
	@Override
	protected void addArgumentResolvers(List argumentResolvers) {
		this.configurers.addArgumentResolvers(argumentResolvers);
	}

	@Override
	protected void addReturnValueHandlers(List returnValueHandlers) {
		this.configurers.addReturnValueHandlers(returnValueHandlers);
	}

	@Override
	protected void configureMessageConverters(List> converters) {
		this.configurers.configureMessageConverters(converters);
	}

	@Override
	protected void extendMessageConverters(List> converters) {
		this.configurers.extendMessageConverters(converters);
	}

	@Override
	protected void configureHandlerExceptionResolvers(List exceptionResolvers) {
		this.configurers.configureHandlerExceptionResolvers(exceptionResolvers);
	}

	@Override
	protected void extendHandlerExceptionResolvers(List exceptionResolvers) {
		this.configurers.extendHandlerExceptionResolvers(exceptionResolvers);
	}

	@Override
	@Nullable
	protected Validator getValidator() {
		return this.configurers.getValidator();
	}

	@Override
	@Nullable
	protected MessageCodesResolver getMessageCodesResolver() {
		return this.configurers.getMessageCodesResolver();
	}

}

源码分析@EnableWebMvc导致静态链接无法加载_第1张图片
进入资源配置后,对WebJars(就是对于一些前端的东西封装到Jar里面去了)的内容进行加载,如果没有的话就从resourceProperties中找
源码分析@EnableWebMvc导致静态链接无法加载_第2张图片
进入ResourceProperties中看看,可以看到定义了很多个classpath,这些都是资源文件加载的根目录
源码分析@EnableWebMvc导致静态链接无法加载_第3张图片
因此我们的资源文件写在这几个目录下就会被加载,因此我们又来回头看看为什么加了@EnableWebMvc就让它失效了呢?
可以看到对WebMvcConfigurationSupport的自动配置是在没有自定义WebMvcConfigurationSupport的前提下
源码分析@EnableWebMvc导致静态链接无法加载_第4张图片
那就顺藤摸瓜,看看WebMvcConfigurationSupport的子类都有些什么
源码分析@EnableWebMvc导致静态链接无法加载_第5张图片
很明显,和资源配置有关的除了自己就剩了DelegatingWebMvcConfiguration了,因此进入DelegatingWebMvcConfiguration,有没有感觉到眼熟呢?没错就是我们前面看间@EnableWebMvc中@import的一个class。

原因:所以原因就找到了,是因为配置了@EnableWebMvc,因此就相当于自定义了DelegatingWebMvcConfiguration,也就相当于实现了WebMvcConfigurationSupport,因此再配合上@ConditionOnMissing注解,理所当然的自动配置就消失了,因此资源文件就不能加载出来了。

你可能感兴趣的:(项目整理)