SpringMVC源码分析(2)DispatcherServlet的初始化

简介:

DispatcherServlet的初始化,是在org.springframework.web.context.ContextLoaderListener完成加载后,才开始的。这时候WebApplicationContext(包含DAO,Service等)已经初始完毕。

DispatcherServlet的初始过程主要完成

1.WebApplicationContext父子容器维护

2.初始化Servlet策略

本文主要内容

  1. DispatcherServlet的集成体系

  2. DispatcherServlet初始化过程


1.DispatcherServlet的继承体系


3.jpg

DispatcherServlet是个普通servlet,是访问入口。明白了继承体系,方便梳理初始化模板。

2.DispatcherServlet初始化过程

4.jpg

2.1 init

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public  final  void  init()  throws  ServletException {
 
    // Set bean properties from init parameters.
    //将Servlet配置的参数封装到pvs变量中
    try  {
       PropertyValues pvs =  new  ServletConfigPropertyValues(getServletConfig(),  this .requiredProperties);
       BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess( this );
       ResourceLoader resourceLoader =  new  ServletContextResourceLoader(getServletContext());
       bw.registerCustomEditor(Resource. class new  ResourceEditor(resourceLoader));
       initBeanWrapper(bw); //bw就是DispatcherServlet
       bw.setPropertyValues(pvs,  true );
    }
 
    // 让子类实现
    initServletBean();
 
    if  (logger.isDebugEnabled()) {
       logger.debug( "Servlet '"  + getServletName() +  "' configured successfully" );
    }
}

2.2 initServletBean方法

1
2
3
4
5
protected  final  void  initServletBean()  throws  ServletException {
       this .webApplicationContext = initWebApplicationContext();
       initFrameworkServlet(); //子类可以实现
 
}

初始化webApplicationContext ;初始化FrameworkServlet

2.3 initWebApplicationContext方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
protected  WebApplicationContext initWebApplicationContext() {
    WebApplicationContext wac = findWebApplicationContext();
    if  (wac ==  null ) {
       // No fixed context defined for this servlet - create a local one.
       WebApplicationContext parent =
             WebApplicationContextUtils.getWebApplicationContext(getServletContext());
       wac = createWebApplicationContext(parent);
    }
 
    if  (! this .refreshEventReceived) {
       // Apparently not a ConfigurableApplicationContext with refresh support:
       // triggering initial onRefresh manually here.
       onRefresh(wac); ////调用DispatcherServlet.initStrategies入口
    }
 
    if  ( this .publishContext) {
       // Publish the context as a servlet context attribute.
       String attrName = getServletContextAttributeName();
       getServletContext().setAttribute(attrName, wac);
       ...
       }
    }
 
    return  wac;
}
 
protected  WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
    Class<?> contextClass = getContextClass();
    ConfigurableWebApplicationContext wac =
          (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
    wac.setParent(parent); //维护双亲委派
    wac.setServletContext(getServletContext());
    wac.setServletConfig(getServletConfig());
    wac.setNamespace(getNamespace());
    wac.setConfigLocation(getContextConfigLocation());
    //调用DispatcherServlet.initStrategies入口
    wac.addApplicationListener( new  SourceFilteringListener(wac,  new  ContextRefreshListener()));
    postProcessWebApplicationContext(wac);
    wac.refresh();
    return  wac;
}
 
private  class  ContextRefreshListener  implements  ApplicationListener<ContextRefreshedEvent> {
 
    public  void  onApplicationEvent(ContextRefreshedEvent event) {
       FrameworkServlet. this .onApplicationEvent(event);
    }
}

2.5.initStrategies方法

1
2
3
4
5
6
7
8
9
10
protected  void  initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
}

初始化9个组件。

初始化组件过程,大体都是先从容器中获取,获取不到,则调用getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface)方法。

默认配置来自DispatcherServlet.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
 
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
 
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
 
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
 
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
    org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
    org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
 
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
 
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

2.6.initHandlerMappings方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private  void  initHandlerMappings(ApplicationContext context) {
    this .handlerMappings =  null ;
    if  ( this .detectAllHandlerMappings) {
       // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
       Map<String, HandlerMapping> matchingBeans =
             BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping. class true false );
       if  (!matchingBeans.isEmpty()) {
          this .handlerMappings =  new  ArrayList<HandlerMapping>(matchingBeans.values());
          // We keep HandlerMappings in sorted order.
          OrderComparator.sort( this .handlerMappings);
       }
    }
    else  {
...
    }
 
    }
}

将spring mvc容器中HandlerMapping对象赋给handlerMappings 列表。这些对象都是在标签解析时,自动加载入容器中的。具体<SpringMVC源码分析(1)标签解析>

2.7 initHandlerAdapters方法

与initHandlerMappings思路完全一致。




本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1877958,如需转载请自行联系原作者

相关文章
|
XML 前端开发 Java
源码分析系列教程(05) - 手写SpringMVC
源码分析系列教程(05) - 手写SpringMVC
37 0
|
21天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
31 1
|
22天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
25 1
|
19天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
21 0
|
6月前
|
前端开发 Java 应用服务中间件
SpringMVC源码分析之策略对象初始化
SpringMVC源码分析之策略对象初始化
62 0
|
缓存 容器
从源码分析SpringMVC核心处理流程
从源码分析SpringMVC核心处理流程
109 0
从源码分析SpringMVC核心处理流程
|
XML 设计模式 JSON
图文源码分析Spring MVC请求映射原理、执行流程
图文源码分析Spring MVC请求映射原理、执行流程
255 0
图文源码分析Spring MVC请求映射原理、执行流程
|
存储 Java 应用服务中间件
SpringMVC源码分析 DispatcherServlet源码分析
SpringMVC源码分析 DispatcherServlet源码分析
SpringMVC源码分析 DispatcherServlet源码分析
|
设计模式 缓存 前端开发
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
web九大组件之---HandlerAdapter适配器模式实践源码分析【享学Spring MVC】
|
前端开发 Java Spring
【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制)(下)
【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制)(下)
【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制)(下)