源码分析@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<WebMvcConfigurer> 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<HandlerMethodArgumentResolver> argumentResolvers) {
		this.configurers.addArgumentResolvers(argumentResolvers);
	}

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

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

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

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

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

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

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

}

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值