1、修改配置文件
SpringBoot自动配置中,存在大量的属性绑定,通过修改配置文件达到修改默认值的功能,例如:WebMvcAutoConfigurationAdapter 自动注入时,会属性绑定WebMvcProperties与ResourceProperties,后面配置使用时,会从中取值
@Configuration(
proxyBeanMethods = false
)
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
}
2、编写自定义的配置类 xxxConfiguration;+ @Bean替换、增加容器中默认组件
SpringBoot容器中会存在大量ConditionalOnMissingBean判断条件,通过该方式可达到替换的作用;同时SpringBoot也存在大量循环判断容器所有某类组件,通过该方式可达到增加的作用。
//容器中注入InternalResourceViewResolver 可以达到替换
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
}
//异常处理解析器,会根据循环遍历所有的HandlerExceptionResolver,所以往容器中注入时可达到新增
for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
3、xxxxxCustomizer
存在xxxxCustomizerBeanPostProcessor实现BeanPostProcessor,实例创建完成会调用postProcessBeforeInitialization方法,postProcessBeforeInitialization会调用xxxxxCustomizer中customize的方法,达到修改配置值的作用
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebServerFactory) {
this.postProcessBeforeInitialization((WebServerFactory)bean);
}
return bean;
}
private void postProcessBeforeInitialization(WebServerFactory webServerFactory) {
((Callbacks)LambdaSafe.callbacks(WebServerFactoryCustomizer.class, this.getCustomizers(), webServerFactory, new Object[0]).withLogger(WebServerFactoryCustomizerBeanPostProcessor.class)).invoke((customizer) -> {
customizer.customize(webServerFactory);
});
}
4、实现 WebMvcConfigurer 即可定制化web功能
通过实现WebMvcConfigurer 中特定的方法实现web定制化功能,如自定义内容协商策略
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* 自定义内容协商策略
* @param configurer
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Map<String, MediaType> mediaTypes = new HashMap<>();
mediaTypes.put("json",MediaType.APPLICATION_JSON);
mediaTypes.put("xml",MediaType.APPLICATION_XML);
mediaTypes.put("gg",MediaType.parseMediaType("application/x-guigu"));
//指定支持解析哪些参数对应的哪些媒体类型
ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
HeaderContentNegotiationStrategy headeStrategy = new HeaderContentNegotiationStrategy();
configurer.strategies(Arrays.asList(parameterStrategy,headeStrategy));
}
}
5、@EnableWebMvc + WebMvcConfigurer
全面接管SpringMvc,所有规则全部自己重新配置; 实现定制和扩展功能,该配置会使SpringBoot中WebMvcAutoConfiguration失效,只能保证SpringMvc的最基础的使用,静态资源、欢迎页等都无法使用,需要自己定制化。
- 失效原理
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
//注入DelegatingWebMvcConfiguration,DelegatingWebMvcConfiguration能保证SpringMvc的最基础的使用
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
}
//容器中存在WebMvcConfigurationSupport,所以不会生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
public class WebMvcAutoConfiguration {
}