RequestMappingHandlerMapping默认初始化方式

295 阅读2分钟

前言

接上文开始学习springmvc默认组件初始化流程,不过这些组件的初始化方式都差不多,这次就选择HandlerMapping做笔记了.

DispatcherServlet中的初始化

接Servlet初始化时会调用DispatcherServlet#initHandlerMappings()方法说起,initHandlerMappings方法会调用initHandlerMappings来初始化handlerMappings组件.

initHandlerMappings的概要流程

  1. 判断是否应该启用容器中存在的所有HandlerMapping(默认是ture).
  2. 如果启用容器中存在的所有HanlderMapping则直接获取HandlerMapping的实现对象保存起来.
  3. 如果未启用容器中存在的所有HanlderMapping则根据默认名称handlerMapping从容器中检索HandlerMapping.
  4. 走完2/3逻辑之后并没有找到可用的handlerMapping则需要走默认策略加载HandlerMapping.

DispatcherServlet中的默认策略

protected <T> List<T>  getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface){}

加载默认策略的方法前面如上所示,其中strategyInterface字段就是配置了默认实现的接口了,大致逻辑如下:

  1. 加载默认配置文件资源DispatcherServlet.properties.
  2. 根据strategyInterface的名称获取对应的value.
  3. 如果value存在则使用,分隔符把value拆成className数组.
  4. 使用context.getAutowireCapableBeanFactory().createBean(clazz)把class创建成对应的实例(使用这种方法可以使创建的实例经历一次prototype的生命周期,填充很多依赖于applicationContext才能获取的对象).
  5. 如果没有默认策略则直接返回一个空集合.

RequestMappingHandlerMapping的初始化

RequestMappingHandlerMapping属于HandlerMapping的默认实现策略之一,从上文可以知道他在springmvc中的默认初始化时机了,接下来就要学习他默认初始化时做了哪些工作. RequestMappingHandlerMapping的初始化工作是由afterPropertiesSet()这个bean创建完成的回调方法处理的,主要方法调用流程为RequestMappingHandlerMapping#afterPropertiesSet -> AbstractHandlerMethodMapping#afterPropertiesSet -> AbstractHandlerMethodMapping#initHandlerMethods,重点就在于initHandlerMethods如果将我们的@RequestMapping方法注册到HandlerMapping中来了. 这个方法大概可以分为

protected void initHandlerMethods() {
            for (String beanName : getCandidateBeanNames()) {
                    if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
                            processCandidateBean(beanName);
                    }
            }
            handlerMethodsInitialized(getHandlerMethods());
	}