initLocaleResolver
private void initLocaleResolver(ApplicationContext context) { try { this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class); } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); } }
若我们自己配置配置LocaleResolver
,会调用getDefaultStrategy
去获取默认的处理器:
默认处理器在DispatcherServlet.properties
这个文件里,如下:
initHandlerMappings
原理同下,默认值为:
开启了@EnableMvc注解后,拿到的HandlerMapping为:
不开启这个注解:解析配置文件得到默认值:
initHandlerAdapters
原理同下,默认值为:
initHandlerExceptionResolvers
处理方式同initViewResolvers
,因此此处不再解释。默认会配置如下三个Bean(若我们自己都没有配置的话):
关于详细时候,后面会专门有所概述
initRequestToViewNameTranslator
逻辑同上,默认值为:
initViewResolvers
视图解析器,稍微复杂点。
private void initViewResolvers(ApplicationContext context) { this.viewResolvers = null; if (this.detectAllViewResolvers) { // 如果detectAllViewResolvers为true,那么就会去容器里找所有的(包含所有祖先上下文)容器里的所有的此接口下的此类的bean,最后都放进去(可以有多个嘛) Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false); if (!matchingBeans.isEmpty()) { this.viewResolvers = new ArrayList<>(matchingBeans.values()); // We keep ViewResolvers in sorted order. 保持排序性 AnnotationAwareOrderComparator.sort(this.viewResolvers); } } else { try { ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class); // 这一步,使用了singletonList,是为了性能考虑,节约内存 this.viewResolvers = Collections.singletonList(vr); } } // 若还为null,就采用默认配置的视图解析器InternalResourceViewResolver if (this.viewResolvers == null) { this.viewResolvers = getDefaultStrategies(context, ViewResolver.class); } }
下面说说,什么时候detectAllViewResolvers会为false呢?
默认值为true,回去容器里找到所有的视图解析器的Bean。我们可以通过init-param配置为false,来关闭这个(不建议)
另外,需要注意的是,我们发现虽然我们没有自己注册Bean进去,但是在matchingBeans这一步时,已经有值了,怎么回事呢?继续扣源码发现:我有这个注解@EnableWebMvc:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(DelegatingWebMvcConfiguration.class) public @interface EnableWebMvc { }
会发现这个注解导入了DelegatingWebMvcConfiguration,而它是
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}
的子类,而WebMvcConfigurationSupport我们就比较熟悉了,它默认配置注册了很多东西到MVC的配置中,所以我们才会发现那个时候就已经matchingBeans有值了。那我们去掉@EnableWebMvc再试试呢?
我们发现,从容器里就拿不出Bean了,只能读取配置文件里的默认值了~
initFlashMapManager
默认值为:
总结
DispatcherServlet
的Spring MVC9大组件的介绍,以及他们的初始化的一个流程就到这了。还是那句话,理解了这些来龙去脉,会更有助于我们的流畅的使用、定制Spring MVC的一些功能~