spring-mvc中,handlerMapping的初始化过程

我们知道,在访问时,最终的请求都会经过下面的方法,有兴趣的同学可自行查看源代码,这里就不贴出来了。

org.springframework.web.servlet.DispatcherServlet#doDispatch

代码中的第一步就是,获取mappedHandler

// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);

我们查看getHandler方法的源码,如下

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;
}

发现,就是循环this.handlerMappings,从每个handlerMapping中,获取Handler。那么,this.handlerMappings是怎么初始化的?下面进行详细介绍。

当我们使用springmvcservlet-servlet.xml作为spring-mvc的配置文件时,需要加上一个配置,如下:


很多同学可能从来没有细想过,为什么要加上这个东西

在spring启动的过程当中,

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
                contextRefresh.end();
            }
        }
    }

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

方法中,会对springmvcservlet-servlet.xml文件进行解析,当解析到mvc标签时,最终会读取到spring-webmvc模块下,resources/META-INF/spring.handler文件中内容。内容如下:

http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler

拿到mvc标签的处理器

org.springframework.web.servlet.config.MvcNamespaceHandler

MvcNamespaceHandler中有一个初始化方法,我们可以查看一下,代码如下:

public void init() {
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
        registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
        registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
        registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
        registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
}

我们可以看到annotation-driven名称后面,有一个解析

AnnotationDrivenBeanDefinitionParser

这个解析器是用来解析annotation-driven。在这里,初始化了HandleringMapping。将

RequestMappingHandlerMapping
BeanNameUrlHandlerMapping

的beandefintion注册到了defaultlistablebeanfactory对象里面。

最后,在spring启动的最后一步,会进行handlerMapping的初始化,将对象放入到HandleringMapping对象放入到this.handleringMappings列表中。

// Last step: publish corresponding event.
finishRefresh();

你可能感兴趣的:(spring-mvc中,handlerMapping的初始化过程)