SpringMVC源码(三):九大内置组件初始化

  在源码(二):MVC容器启动的分析中,MVC容器刷新完成后,通过发布事件及事件监听处理器来初始化MVC的九大组件,下面来分析下这九大组件初始化的细节。

概览

  初始化MVC组件,DispatcherServlet#initStrategies 核心代码:

 1 // 初始化组件
 2 protected void initStrategies(ApplicationContext context) {
 3    // 初始化 MultipartResolver:主要用来处理文件上传.如果定义过当前类型的bean对象,那么直接获取,如果没有的话,可以为null
 4    initMultipartResolver(context);
 5    // 初始化 LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver),
 6    // 基于session的配置(SessionLocaleResolver),基于cookie的配置(CookieLocaleResolver)
 7    initLocaleResolver(context);
 8    // 初始化 ThemeResolver:主要用来设置主题Theme
 9    initThemeResolver(context);
10    // 初始化 HandlerMapping:映射器,用来将对应的request跟controller进行对应
11    initHandlerMappings(context);
12    // 初始化 HandlerAdapter:处理适配器,主要包含Http请求处理器适配器,简单控制器处理器适配器,注解方法处理器适配器
13    initHandlerAdapters(context);
14    // 初始化 HandlerExceptionResolver:基于HandlerExceptionResolver接口的异常处理
15    initHandlerExceptionResolvers(context);
16    // 初始化 RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或逻辑视图名称,
17    // 并且在该方法中没有直接往response的输出流里面写数据的时候,spring将会采用约定好的方式提供一个逻辑视图名称
18    initRequestToViewNameTranslator(context);
19    // 初始化 ViewResolver: 将ModelAndView选择合适的视图进行渲染的处理器
20    initViewResolvers(context);
21    // 初始化 FlashMapManager: 提供请求存储属性,可供其他请求使用
22    initFlashMapManager(context);
23 }

  DispatcherServlet中持有SpringMVC内置的九大组件属性。

 

一、初始化文件上传组件

  初始化文件上传组件initMultipartResolver(context),DispatcherServlet#initMultipartResolver核心伪代码:

 1 // MultipartResolver对象在MVC容器中的beanName
 2 public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
 3 
 4 // 初始化MultipartResolver
 5 private void initMultipartResolver(ApplicationContext context) {
 6    try {
 7       // 从spring上下文获取名称为 multipartResolver ,类型为MultipartResolver的Bean
 8       this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
 9    }
10    // 若未定义bean信息,默认为空
11    catch (NoSuchBeanDefinitionException ex) {
12       this.multipartResolver = null;
13    }
14 }

  从容器中获取beanName为multipartResolver,类型为MultipartResolver的bean对象,若未设置该bean,默认为空。

二、初始化参数解析器

  初始化参数解析器initLocaleResolver(context),DispatcherServlet#initLocaleResolver核心伪代码:

 1 // LocaleResolver对象在MVC容器中的beanName
 2 public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
 3 
 4 // 初始化参数解析器
 5 private void initLocaleResolver(ApplicationContext context) {
 6    try {
 7       // 从上下文中获取Bean名称为 LocaleResolver的对象
 8       this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);     
 9    }
10    catch (NoSuchBeanDefinitionException ex) {
11       // 从配置文件中获取默认的AcceptHeaderLocaleResolver对象
12       this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
13    }
14 }

 从容器中获取beanName为localeResolver,类型为LocaleResolver的bean对象,若未设置该bean,获取默认的LocaleResolver,AcceptHeaderLocaleResolver对象。

三、初始化主题资源

  初始化主题资源initThemeResolver(context),DispatcherServlet#initThemeResolver核心伪代码:
 1 // ThemeResolver对象在MVC容器中的beanName
 2 public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
 3 
 4 // 初始化主题资源对象
 5 private void initThemeResolver(ApplicationContext context) {
 6    try {
 7       // 从上下文中获取Bean名称为 themeResolver的对象
 8       this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
 9    }
10    catch (NoSuchBeanDefinitionException ex) {
11       // 从配置文件中获取默认的FixedThemeResolver
12       this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
13    }
14 }

  从容器中获取beanName为themeResolver,类型为ThemeResolver的bean对象,若未设置该bean,获取默认的ThemeResolver,FixedThemeResolver对象。

四、初始化HandlerMapping映射器

  初始化HandlerMapping映射器initHandlerMappings(context), DispatcherServlet#initHandlerMappings核心伪代码:

 1 //HandlerMapping对象在MVC容器中的beanName
 2 public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
 3 
 4 // 初始化HandlerMapping映射器
 5 private void initHandlerMappings(ApplicationContext context) {
 6    // 将handlerMappings置空
 7    this.handlerMappings = null;
 8 
 9    // 如果开启探测功能,则扫描已注册的HandlerMapping的bean,添加到handlerMappings中
10    if (this.detectAllHandlerMappings) {
11       // 扫描已注册的handlerMapping的bean
12       Map<String, HandlerMapping> matchingBeans =
13             BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
14       // 添加到handlerMappings中,并进行排序
15       if (!matchingBeans.isEmpty()) {
16          this.handlerMappings = new ArrayList<>(matchingBeans.values());
17          AnnotationAwareOrderComparator.sort(this.handlerMappings);
18       }
19    }
20    // 如果关闭探测功能,则获取Bean名称为handlerMapping对应的bean,将其添加到handlerMappings
21    else {
22        HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
23        this.handlerMappings = Collections.singletonList(hm);
24    }
25    // 若未配置handlerMapping,获取默认配置的handlerMapping -> BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping
26    if (this.handlerMappings == null) {
27       // 获取默认的handlerMapping策略
28       this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
29    }
30 }

  1、判断是否开启了HandlerMapping自动探测功能,若功能开启,获取所有HandlerMapping类型的对象,并添加至handlerMappings集合中,包含DispatcherServlet.properties文件中配置的默认HandlerMapping:BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping;

  2、若关闭了HandlerMapping自动探测功能,获取beanName为handlerMapping,类型为HandlerMapping的对象并添加至handlerMappings集合中;

  3、若未配置handlerMappings,获取SpringMVC默认的HandlerMapping实现,BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping。

  注意:在初始化HandlerMapping组件时,会初始化DispatcherServlet中的handlerMappings属性,用于在MVC请求流程中,获取HandlerExecutionChain处理器执行器链。

五、初始化HandlerAdapter处理适配器

  初始化处理适配器initHandlerAdapters(context), DispatcherServlet#initHandlerAdapters核心伪代码:

 1 // HandlerAdapter对象在MVC容器中的beanName
 2 public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
 3 
 4 // 初始化HandlerAdapters适配处理器
 5 private void initHandlerAdapters(ApplicationContext context) {
 6    this.handlerAdapters = null;
 7 
 8    // 如果开启探测功能,则扫描已注册的HandlerAdapter的bean,添加到handlerAdapters中
 9    if (this.detectAllHandlerAdapters) {
10       // 探测容器中所有的HandlerAdapter适配处理器,包括父类中的
11       Map<String, HandlerAdapter> matchingBeans =
12             BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
13       // 容器中存在HandlerAdapter类型的bean
14       if (!matchingBeans.isEmpty()) {
15          // 添加至handlerAdapters集合中
16          this.handlerAdapters = new ArrayList<>(matchingBeans.values());
17          // 对集合handlerAdapters做排序
18          AnnotationAwareOrderComparator.sort(this.handlerAdapters);
19       }
20    }
21    // 若未开启探测功能
22    else {
23       // 获取容器中beanName为handlerAdapter,类型为HandlerAdapter的bean对象
24       HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
25       // 添加至handlerAdapters集合中
26       this.handlerAdapters = Collections.singletonList(ha);
27    }
28 
29    // 如果未获得到,则获得默认配置的HandlerAdapter类,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter,RequestMappingHandlerAdapter
30    if (this.handlerAdapters == null) {
31       // SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter、HandlerFunctionAdapter
32       this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
33    }
34 }

  1、判断是否开启了HandlerAdapter自动探测功能,若功能开启,获取所有HandlerAdapter类型的对象,并添加至handlerAdapters集合中;

  2、若关闭了HandlerAdapter自动探测功能,获取beanName为handlerAdapter,类型为HandlerAdapter的对象并添加至handlerAdapters集合中;

  3、若未配置HandlerAdapter,获取SpringMVC默认的HandlerAdapter实现,SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter、HttpRequestHandlerAdapter。

六、初始化HandlerExceptionResolver异常处理器

  初始化处理适配器initHandlerExceptionResolvers(context), DispatcherServlet#initHandlerExceptionResolvers核心伪代码:

 1 // HandlerExceptionResolver对象在MVC容器中的beanName
 2 public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
 3 
 4 // 初始化异常处理器
 5 private void initHandlerExceptionResolvers(ApplicationContext context) {
 6    // 置空 handlerExceptionResolver 处理
 7    this.handlerExceptionResolvers = null;
 8 
 9    // 自动扫描handlerExceptionResolver类型的bean
10    if (this.detectAllHandlerExceptionResolvers) {
11       // 获取容器中所有HandlerExceptionResolver类型的bean对象
12       Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
13             .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
14       // 容器中存在HandlerExceptionResolver类型的bean对象
15       if (!matchingBeans.isEmpty()) {
16          // 添加至handlerExceptionResolvers集合中
17          this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());
18          // 排序
19          AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
20       }
21    }
22    // 获取名字为HANDLER_EXCEPTION_RESOLVER_BEAN_NAME的bean
23    else {
24        // 获取容器中beanName为handlerExceptionResolver, 类型为HandlerExceptionResolver的bean对象
25        HandlerExceptionResolver her =
26              context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
27         // 添加至handlerExceptionResolvers集合中
28        this.handlerExceptionResolvers = Collections.singletonList(her);
29    }
30 
31    // 如果未获得到
32    if (this.handlerExceptionResolvers == null) {
33        // 获取默认配置的handlerExceptionResolver类,ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver,DefaultHandlerExceptionResolver
34       this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
35    }
36 }

  1、判断是否开启了HandlerExceptionResolver自动探测功能,若功能开启,获取所有HandlerExceptionResolver类型的对象,并添加至handlerExceptionResolvers集合中;

  2、若关闭了HandlerExceptionResolver自动探测功能,beanName为handlerExceptionResolver, 类型为HandlerExceptionResolver的bean对象并添加至handlerExceptionResolvers集合中;

  3、若未配置HandlerExceptionResolver,获取SpringMVC默认的HandlerExceptionResolver实现,ExceptionHandlerExceptionResolver,

ResponseStatusExceptionResolver,DefaultHandlerExceptionResolver。

七、初始化RequestToViewNameTranslator视图转化器

  初始化处理适配器initRequestToViewNameTranslator(context), DispatcherServlet#initRequestToViewNameTranslator核心伪代码:

 1 // RequestToViewNameTranslator对象在MVC容器中的beanName
 2 public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
 3 
 4 // 初始化视图转换器
 5 private void initRequestToViewNameTranslator(ApplicationContext context) {
 6    try {
 7       // 获取容器中beanName为viewNameTranslator,类型为RequestToViewNameTranslator的bean对象
 8       this.viewNameTranslator =
 9             context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
10    }
11    catch (NoSuchBeanDefinitionException ex) {
12       // 如果未找到,则获取默认的 RequestToViewNameTranslator 对象,DefaultRequestToViewNameTranslator
13       this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
14    }
15 }

  1、获取容器中beanName为viewNameTranslator,类型为RequestToViewNameTranslator的bean对象;

  2、若未配置ViewNameTranslator,获取SpringMVC默认的RequestToViewNameTranslator实现,DefaultRequestToViewNameTranslator。

八、初始化ViewResolver视图解析器

  初始化处理适配器 initViewResolvers(context), DispatcherServlet#initViewResolvers核心伪代码:

 1 // ViewResolver对象在MVC容器中的beanName
 2 public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
 3 
 4 // 初始化视图解析器
 5 private void initViewResolvers(ApplicationContext context) {
 6    // 置空 viewResolvers 处理
 7    this.viewResolvers = null;
 8 
 9    // 自动扫描 ViewResolver 类型的 Bean
10    if (this.detectAllViewResolvers) {
11       // 获取容器中所有ViewResolver类型的bean对象
12       Map<String, ViewResolver> matchingBeans =
13             BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
14       // 容器中存在ViewResolver类型的bean对象
15       if (!matchingBeans.isEmpty()) {
16          // 添加至viewResolvers集合中
17          this.viewResolvers = new ArrayList<>(matchingBeans.values());
18          // 排序
19          AnnotationAwareOrderComparator.sort(this.viewResolvers);
20       }
21    }
22    // 获得名字为VIEW_RESOLVER_BEAN_NAME的bean
23    else {
24       // 获取容器中beanName为viewResolver, 类型为ViewResolver的bean对象
25       ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
26       // 添加至viewResolvers集合中
27       this.viewResolvers = Collections.singletonList(vr);
28    }
29    
30    // 如果未配置视图解析器ViewResolver,则获取默认配置的ViewResolver对象InternalResourceViewResolver
31    if (this.viewResolvers == null) {
32       this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
33    }
34 }

九、初始化FlashMapManager缓存管理器

  主要用于重定向时的参数传递。

  初始化缓存管理器 initFlashMapManager(context), DispatcherServlet#initFlashMapManager核心伪代码:

 1 // FlashMapManager对象在MVC容器中的beanName
 2 public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
 3 
 4 // 初始化缓存管理器
 5 private void initFlashMapManager(ApplicationContext context) {
 6    try {
 7       // 获取容器中beanName为flashMapManager,类型为FlashMapManager的bean对象
 8       this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
 9    }
10    catch (NoSuchBeanDefinitionException ex) {
11       // 未找到,则获取默认的 FlashMapManager 对象,SessionFlashMapManager
12       this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
13    }
14 }

十、DispatcherServlet默认的策略实现

  可以查看Spring-webmvc子模块中的DispatcherServlet.properties文件,详情如下:
 1 #  DispatcherServlet的策略接口的默认实现类
 2 
 3 org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
 4 
 5 org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
 6 
 7 org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
 8    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
 9    org.springframework.web.servlet.function.support.RouterFunctionMapping
10 
11 org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
12    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
13    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
14    org.springframework.web.servlet.function.support.HandlerFunctionAdapter
15 
16 
17 org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
18    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
19    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
20 
21 org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
22 
23 org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
24 
25 org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

  针对九大组件,获取默认的策略实现,在DispatcherServlet.properties文件中有具体配置,只要根据对应的namespace获取到对应实现类即可。

 

posted @ 2023-02-12 20:39  无虑的小猪  阅读(196)  评论(0编辑  收藏  举报