自定义WebMvcConfigurer、WebMvcConfigurationSupport失效之谜
注解-@EnableWebMVC源码@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(DelegatingWebMvcConfiguration.class)public @interface EnableWebMvc {}意思就是说:如果引用了@EnableWebMVC注解,就会往spri
·
先贴总结
- 实现
WebMvcConfigurer
: 不会覆盖WebMvcAutoConfiguration
的配置 - 实现
WebMvcConfigurer
+注解@EnableWebMvc
:会覆盖WebMvcAutoConfiguration
的配置 - 继承
WebMvcConfigurationSupport
:会覆盖WebMvcAutoConfiguration
的配置 - 继承
DelegatingWebMvcConfiguration
:会覆盖WebMvcAutoConfiguration
的配置
源码分析
注解-@EnableWebMVC
源码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
意思就是说:如果引用了@EnableWebMVC
注解,就会往spring容器中注入了一个DelegatingWebMvcConfiguration
来统一管理所有的配置类
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
...
}
注解-@SpringBootApplication
源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
这里引用了@EnableAutoConfiguration
注解
注解-@EnableAutoConfiguration
源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
注解@AutoConfigurationPackage
的主要作用就是:将主程序类所在包及所有子包下的组件到扫描到spring容器中。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
AutoConfigurationImportSelector
的作用可以参考:springboot源码自动装配-AutoConfigurationImportSelector
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
...
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 是否启用自动配置
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
// 获取META-INF/spring-autoconfigure-metadata.properties文件的配置,返回AutoConfigurationMetadata类
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
// 获取自动配置类,返回AutoConfigurationEntry
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
// 返回要自动配置的类名
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
...
}
意思就是:如果引用了@EnableAutoConfiguration
注解,就会往spring容器中注入两个类
AutoConfigurationPackages.Registrar
:扫包AutoConfigurationImportSelector
:等所有类全加载到spring容器之后扫描配置类
配置类-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})
,当Spring容器中不存在WebMvcConfigurationSupport
bean,WebMvcAutoConfiguration
才会注入- 如果有配置文件继承了
DelegatingWebMvcConfiguration
,或者WebMvcConfigurationSupport
,或者配置类注解了@EnableWebMvc
,那么WebMvcAutoConfiguration
将不会被自动配置,而是使用WebMvcConfigurationSupport
的配置。那么!!!!所有实现了WebMvcConfigurer
的配置类有可能会 全部失效!!!!!
配置类-WebMvcConfigurationAdapter
WebMvcConfigurationAdapter
已经废弃,最好用WebMvcConfigurer
代替
更多推荐
已为社区贡献1条内容
所有评论(0)