Spring启动原理和可扩展设计分析( 二 )


  1. web.xml 里的context-param找contextClass
  2. 没有的话就加载默认:spring jar里ContextLoader.properties写的XmlWebApplicationContext
web.mxl + DispatcherServlet
<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启动原理和可扩展设计分析

文章插图
 
spring mvc
Spring MVC的入口是Controller , 那么解析Controller的东西自然就是SpringMVC的入口了 。
这个入口就是:
RequestMappingHandlerMapping
这个东西继承了3个Aware
  1. ApplicationAware(Spring web)
  2. ServletContextAware (Spring web)
  3. 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启动原理和可扩展设计分析】


推荐阅读