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