0
点赞
收藏
分享

微信扫一扫

handlerMappings初始流程分析-3

忆北文学摄影爱好员 2022-02-16 阅读 15
java

org.springframework.web.servlet.DispatcherServlet#initStrategies

org.springframework.web.servlet.DispatcherServlet#initHandlerMappings

private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;
        //默认为true
        if (this.detectAllHandlerMappings) {
            // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
            //从容器里获取HandlerMapping的bean,那么这个HandlerMapping是在什么时候注入容器的呢?
            //原来是  <mvc:annotation-driven></mvc:annotation-driven>开启了这个注解
            //org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse
            Map<String, HandlerMapping> matchingBeans =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerMappings = new ArrayList<>(matchingBeans.values());
                // We keep HandlerMappings in sorted order.
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        }
        else {
            try {
                HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerMapping later.
            }
        }
​
        // Ensure we have at least one HandlerMapping, by registering
        // a default HandlerMapping if no other mappings are found.
        //如果没有handlerMappings则读取环境变量下的默认配置文件DispatcherServlet.properties
        if (this.handlerMappings == null) {
            this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
            if (logger.isTraceEnabled()) {
                logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
                        "': using default strategies from DispatcherServlet.properties");
            }
        }

总结:从容器里获取HandlerMapping的bean,那么这个HandlerMapping是在什么时候注入容器的呢? 原来是 mvc:annotation-driven/mvc:annotation-driven开启了这个注解 org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse

这里注册了2个bean

1.

RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);

2.

// Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
MvcNamespaceUtils.registerDefaultComponents(context, source);

至此2个bean已经注册到容器完成

解析完之后会在这里使用,通过处理器映射器找到对应的处理器适配器

org.springframework.web.servlet.DispatcherServlet#getHandler

    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        if (this.handlerMappings != null) {
            for (HandlerMapping mapping : this.handlerMappings) {
                HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }
        return null;
    }

总结:通过初始化9大组件,然后开启 mvc:annotation-driven/mvc:annotation-driven,最后通过spring的api函数手动注入2个HandlerMapping,分别是RequestMappingHandlerMapping和BeanNameUrlHandlerMapping

举报

相关推荐

0 条评论