首先看下WebMvcAutoConfiguration 这个类的声明
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {}
此时@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)表明没有WebMvcConfigurationSupport.class这个类就进行下面的配置.
注: 看@EnableWebMvc的声明
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({DelegatingWebMvcConfiguration.class}) public @interface EnableWebMvc { }
如果使用了该注解,@Import({DelegatingWebMvcConfiguration.class})会把这个类进行导入.
看下这个类的声明
@Configuration public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}
说明这个类是WebMvcConfigurationSupport 的类型.
则WebMvcAutoConfiguration类中的数据不会进行读取分析了.
此时会读取WebMvcAutoConfiguration 的内容.WebMvcAutoConfiguration 中有一个内部类WebMvcAutoConfigurationAdapter.看该类的声明
@Configuration
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter
implements WebMvcConfigurer, ResourceLoaderAware {}
@Import(EnableWebMvcConfiguration.class)导入了EnableWebMvcConfiguration这个类,看这个类的声明
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {}
继承了DelegatingWebMvcConfiguration 这个类,看这个类的声明
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired(
required = false
)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
}
这个类也是一个配置类,并把环境中所有的WebMvcConfigurer全部配置到了WebMvcConfigurerComposite这个代理类中,方便后续配置的使用.
这就是为什么一般使用实现这个WebMvcConfigurer接口的方式,来配置环境内容.