- web.xml 里的context-param找contextClass
- 没有的话就加载默认:spring jar里ContextLoader.properties写的XmlWebApplicationContext
<servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet>DispatcherServlet基于Servlet生命周期会在JAVAx.servlet.GenericServlet.init()初始化spring容器
springboot
DispatcherServletAutoConfiguration
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServlet dispatcherServlet() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest( this.webMvcProperties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest( this.webMvcProperties.isDispatchTraceRequest()); dispatcherServlet.setThrowExceptionIfNoHandlerFound( this.webMvcProperties.isThrowExceptionIfNoHandlerFound()); return dispatcherServlet; }Spring MVC原理接着上面的web原理
Dispatcher
Dispatcher是一个Servlet , 是spring web的入口 , 来看下spring的dispatcher如何处理请求

文章插图
spring mvc
Spring MVC的入口是Controller , 那么解析Controller的东西自然就是SpringMVC的入口了 。
这个入口就是:
RequestMappingHandlerMapping这个东西继承了3个Aware
- ApplicationAware(Spring web)
- ServletContextAware (Spring web)
- EmbeddedValueResolverAware (Spring context)
通过Aware , Spring mvc就这么起来了!并且能够自定义解析各种注解RequestMappingHandlerMapping
内部维护一个Map<T, HandlerMethod> handlerMethods , T就是Controller的类
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements MatchableHandlerMapping, EmbeddedValueResolverAware { /** 1. 初始化 */ public void afterPropertiesSet() { initHandlerMethods(); } /** 2. 扫描所有Object的bean , 扫描Controller、RequestMapping 3. 扫描每个controller的web请求方法 , 写入到handlerMethods里 , 以后处理请求时用来对应查找 */protected void initHandlerMethods() {String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); for (String beanName : beanNames) { if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(beanName))){ //查找web请求方法 detectHandlerMethods(beanName); } } handlerMethodsInitialized(getHandlerMethods()); } @Override protected boolean isHandler(Class<?> beanType) { return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) || (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null)); } /** 4. 处理web请求时负责找到对应的处理方法 */ @Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } /** 组装HandlerExecutionChain , 里面主要包括处理列表: List<HandlerInterceptor> interceptorList; */ return getHandlerExecutionChain(handler, request); }}
【Spring启动原理和可扩展设计分析】
推荐阅读
- Redis哨兵原理,我忍你很久了
- 今日头条算法原理—— 3分钟了解今日头条推荐算法原理
- 建议收藏学习 一篇文章弄懂SpringBoot中WebMvcConfigurer
- 核武器原理都知道,为何很多国家倾全力也造不出,究竟难在哪里?
- 深入理解Go的interface内部执行原理
- 一 基本Spring Cloud的微服务架构搭建及应用
- 使用“全新启动”功能重置电脑,还原一个纯净原版的win10系统
- 普洱熟茶饼和生茶,普洱生茶和普洱熟茶减肥原理不同
- 用elastic-job-lite玩转SpringBoot定时器管理
- 如何在重启或启动时执行命令或脚本
