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

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

DispatcherServlet的初始过程主要完成

1.WebApplicationContext父子容器维护

2.初始化Servlet策略

本文主要内容

  1. DispatcherServlet的集成体系
  2. DispatcherServlet初始化过程

1.DispatcherServlet的继承体系

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

2.DispatcherServlet初始化过程

2.1 init

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方法

protected final void initServletBean() throws ServletException {
      this.webApplicationContext = initWebApplicationContext();
      initFrameworkServlet();//子类可以实现

}

初始化webApplicationContext ;初始化FrameworkServlet

2.3 initWebApplicationContext方法

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方法

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

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方法

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思路完全一致。

时间: 2024-10-08 09:05:05

SpringMVC源码分析(2)DispatcherServlet的初始化的相关文章

2.SpringMVC源码分析:DispatcherServlet的初始化与请求转发

一.DispatcherServlet的初始化 在我们第一次学Servlet编程,学java web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根据需要重写一下doGet,doPost方法,跳转到我们定义好的jsp页面.Servlet类编写完之后在web.xml里注册这个Servlet类. 除此之外,没有其他了.我们启动web服务器,在浏览器中输入地址,就可以看到浏览器上输出我们写好的页面.为了更好的理解上面这个过程,你需要学习关于Servl

SpringMVC源码分析(3)DispatcherServlet的请求处理流程

<SpringMVC源码分析(1)标签解析>:介绍了解析过程中,初始化若干组件. <SpringMVC源码分析(2)DispatcherServlet的初始化>:初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的过程. 概览 ①:DispatcherServlet是springmvc中的前端控制器(front controller),负责接收request并将request转发给对应的处理组件. ②:HanlerMappi

SpringMVC源码分析(4)剖析DispatcherServlet重要组件

<SpringMVC源码分析(3)DispatcherServlet的请求处理流程 >简单介绍了一个请求的处理过程, 简略描述了调用过程,并没有涉及过多细节,如url匹配,报文解析转换等. <SpringMVC源码分析(2)DispatcherServlet的初始化>:介绍了servlet的初始化过程,尤其initStrategies方法. 本文主要总结DispatcherServlet几个重要组件的关系. 1.类图 该类图并没有全面的描述SpringMVC相关类,重点说明组件的关

8、SpringMVC源码分析(3):分析ModelAndView的形成过程

首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception方法开始,看看这个牛逼的ModelAndView是怎么开始的,又是怎么结束的: 1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Except

7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()) 这样的方式来执行request的handler方法. 先来分析一下ha.handle方法的调用过程:HandlerAdapter接口有一个抽象实现类AbstractHandlerMethodAdapter,在该抽象类中通过具体方法

springmvc源码分析系列-请求处理流程

接上一篇-springmvc源码分析开头片 上一节主要说了一下springmvc与struts2的作为MVC中的C(controller)控制层的一些区别及两者在作为控制层方面的一些优缺点.今天就结合下面的一张图和上一篇中关于springmvc各个模块之间及各个模块中的类的继承关系的一张图对springmvc的请求处理流程进行一个分析.当然有了springmvc的请求处理流程我们就知道了springmvc是如何在启动的时候去加载或者去解析对应的具体控制器,以及modleAndView使干什么用的

【转】springmvc源码分析链接

SpringMVC源码 SpringMVC源码分析系列 说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而 springmvc是依托着Servlet容器元素来设计的,同时springmvc基于Spring框架,Spring框架想必搞java的同学都很熟 悉. 一进Spring的官网就发现了这样一排醒目的文字, spring可以让我们构造简单的.便携的.又快又易于扩展的基于jvm的系统和应用程序. 没错,基于Spr

SpringMVC源码分析系列

说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时springmvc基于Spring框架,Spring框架想必搞java的同学都很熟悉. 一进Spring的官网就发现了这样一排醒目的文字, spring可以让我们构造简单的.便携的.又快又易于扩展的基于jvm的系统和应用程序. 没错,基于Spring的MVC框架SpringMVC同样也可以构造具有这些特

SpringMVC源码分析(5)剖析重要组件HandlerMapping

<SpringMVC源码分析(4)剖析DispatcherServlet重要组件>   简要介绍了各个组件,从本章开始,针对各个组件,深入介绍.首先是HandlerMapping. HanlerMapping是沟通请求和后端controller映射,是所有请求的入口. 1.类结构介绍 该图只对属性和类层级进行了描述,屏蔽了方法,主要是为了根据内部属性,重点理解Spring HandlerMapping提供功能. 1.1 AbstractHandlerMapping HandlerMapping