spring源码-6-springmvc

HttpServletBean

     建立springmvc框架 与servlet  API的联系。
     init()
public final void init() throws ServletException {
        if (logger.isDebugEnabled()) {
            logger.debug("Initializing servlet '" + getServletName() + "'");
        }

        // Set bean properties from init parameters.
        try {
        //封装加载必要的参数
            PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); 
            //pojo包装类(可以修改pojo属性,通过属性描述器) 
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
            //空实现,子类自定义其它初始化
            initBeanWrapper(bw);  
            bw.setPropertyValues(pvs, true);
        }
        catch (BeansException ex) {
            if (logger.isErrorEnabled()) {
                logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
            }
            throw ex;
        }

        // Let subclasses do whatever initialization they like.
        //子类自定义
        initServletBean();

        if (logger.isDebugEnabled()) {
            logger.debug("Servlet '" + getServletName() + "' configured successfully");
        }
    }

FrameworkServlet

    initServletBean : 子类自定义初始化
protected final void initServletBean() throws ServletException {
        getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
        if (this.logger.isInfoEnabled()) {
            this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
        }
        long startTime = System.currentTimeMillis();

        try {
            this.webApplicationContext = initWebApplicationContext();  //初始化webApplictionContext
            initFrameworkServlet();  //子类自定义初始化 
        }
        catch (ServletException ex) {
            this.logger.error("Context initialization failed", ex);
            throw ex;
        }
        catch (RuntimeException ex) {
            this.logger.error("Context initialization failed", ex);
            throw ex;
        }

        if (this.logger.isInfoEnabled()) {
            long elapsedTime = System.currentTimeMillis() - startTime;
            this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
                    elapsedTime + " ms");
        }
    }
​   springmvc 启动时-》web.xml配置中声明的ContextLoaderListener、DispatcherServlet完成所有任务。

1.ContextLoaderListener(环境加载)

​   完成对spring配置文件的加载。

2.DispatcherServlet(中央调节作用)

​   spring中央控制器,拦截request请求,由handlerMapping -》handler-》DispatcherServlet-》handlerAdapter-》modelAndView》DispatcherServlet-》viewResolver-》response。

ContextLoaderListener

​   加载spring配置文件

​   ContextLoaderListener实现了ServletContextListener,在容器启动时会调用contextInitialized

public void contextInitialized(ServletContextEvent event) {
   initWebApplicationContext(event.getServletContext()); //初始化WebApplicationContext
}
​   继续跟踪如何初始化WebApplicationContext

//省略打印日志
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
   //检验是否已经加载过WebApplicationContext
   //即一个web.xml只能有一个ContextLoaderListener
   if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
      throw new IllegalStateException(
            "Cannot initialize context because there is already a root application context present - " +
            "check whether you have multiple ContextLoader* definitions in your web.xml!");
   }
   long startTime = System.currentTimeMillis();

   try {
      // Store context in local instance variable, to guarantee that
      // it is available on ServletContext shutdown.
      if (this.context == null) {       //初始化WebApplicationContext
         this.context = createWebApplicationContext(servletContext);
      }
      if (this.context instanceof ConfigurableWebApplicationContext) {
         ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
         if (!cwac.isActive()) {
            // The context has not yet been refreshed -> provide services such as
            // setting the parent context, setting the application context id, etc
            if (cwac.getParent() == null) {
               // The context instance was injected without an explicit parent ->
               // determine parent for root web application context, if any.
               ApplicationContext parent = loadParentContext(servletContext);
               cwac.setParent(parent);
            }
            configureAndRefreshWebApplicationContext(cwac, servletContext);
         }
      }
      //将加载的WebApplicationContext 存储在servletContext域中
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

      ClassLoader ccl = Thread.currentThread().getContextClassLoader();
      if (ccl == ContextLoader.class.getClassLoader()) {
         currentContext = this.context;
      }
      else if (ccl != null) {
         //将classload对应的context缓存到map中
         currentContextPerThread.put(ccl, this.context);
      }
      return this.context;
   }
   catch (RuntimeException ex) {
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
      throw ex;
   }
   catch (Error err) {
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
      throw err;
   }
}

DispatcherServlet

​   DispatcherServlet也是Servlet的实现类,对于http各种request(请求)方式会进行拦截,进行统一处理后,解析拦截的请求为handlerMapping(处理器映射器),由handlerMapping映射到handlerAdapter(处理器适配器),由相应的handlerAdapter返回modelAndView对象返回,进行viewResolver(视图解析器渲染)后,response(响应)给client。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                //如果是上传请求,则用上传解析处理
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // Determine handler for the current request.
                //由request寻找对应的handler
                //由handlermapping -》 mappingHandler
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }
            //由mappingHandler - 》 handlerAdapter
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                //执行过滤器操作
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // Actually invoke the handler.
                //由具体的handler执行
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                //视图结果设置
                applyDefaultViewName(processedRequest, mv);
                //再次经过过滤器
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            catch (Throwable err) {
                dispatchException = new NestedServletException("Handler dispatch failed", err);
            }
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Throwable err) {
            triggerAfterCompletion(processedRequest, response, mappedHandler,
                    new NestedServletException("Handler processing failed", err));
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }

//加载策略
protected void initStrategies(ApplicationContext context) {
   initMultipartResolver(context);  //文件处理解析器
   initLocaleResolver(context);  //国际化配置
   initThemeResolver(context);   //主题资源
   initHandlerMappings(context);  //处理器映射器
   initHandlerAdapters(context);  //处理器适配器
   initHandlerExceptionResolvers(context);  //处理异常
   initRequestToViewNameTranslator(context); //逻辑视图
   initViewResolvers(context);    //视图解析
   initFlashMapManager(context);   //请求存储属性
}
​   initMultipartResolver、initLocaleResolver、initThemeResolver相同的原理,只需配置对应的实现类,并保持默认名即可。

​   上述三者不存在时,则默认为null处理,initRequestToViewNameTranslator、initFlashMapManager不同之处为,不存在时,将会以spring默认的策略生成。

//文件请求  配置 multipartResolver  (省略打印日志代码)
private void initMultipartResolver(ApplicationContext context) {
   try {
      //注册multipartResolver 的bean  将MultipartResolver的实现类配置即可
      this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
   }
   catch (NoSuchBeanDefinitionException ex) {
      // Default is no multipart resolver.
      this.multipartResolver = null;
   }
}
​   initHandlerMappings、initHandlerAdapters、initHandlerExceptionResolvers、initViewResolvers相同原理,由DispatcherServlet对应属性生成配置方式。

1.查询所有的映射器/适配器/...

2.只加载配置特定name的映射器/适配器/...

3.加载默认的映射器/适配器/...

private void initHandlerMappings(ApplicationContext context) {
   this.handlerMappings = null;

   //默认开启查询所有的处理器映射器(HandlerMapping)
   if (this.detectAllHandlerMappings) {
      // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
      //加载所有的HandlerMapping
      Map<String, HandlerMapping> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
      if (!matchingBeans.isEmpty()) {
         this.handlerMappings = new ArrayList<>(matchingBeans.values());
         // We keep HandlerMappings in sorted order.
         AnnotationAwareOrderComparator.sort(this.handlerMappings);
      }
   }
   else {
      try {
         //否则将会只加载命名为handlerMapping 的处理器映射器
         HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
         this.handlerMappings = Collections.singletonList(hm);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Ignore, we'll add a default HandlerMapping later.
      }
   }

   // Ensure we have at least one HandlerMapping, by registering
   // a default HandlerMapping if no other mappings are found.
   if (this.handlerMappings == null) {
      //加载spring默认提供的handlerMapping
      this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
   }
}
​   完成配置的初始化,对请求的doDispatch 完成逻辑处理。

//部分代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   boolean multipartRequestParsed = false;

   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

   try {
      ModelAndView mv = null;
      Exception dispatchException = null;

      try {
         //判断是否为multipart请求
         processedRequest = checkMultipart(request);
         multipartRequestParsed = (processedRequest != request);

         // Determine handler for the current request.
         //根据当前请求,遍历handlerMapping  返回HandlerExecutionChain
         mappedHandler = getHandler(processedRequest);
         if (mappedHandler == null || mappedHandler.getHandler() == null) {
            noHandlerFound(processedRequest, response);  //返回404
            return;
         }

         // Determine handler adapter for the current request.
         //由handlerMapping 返回的handler查询匹配的handlerAdapter
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

         // Process last-modified header, if supported by the handler.
         String method = request.getMethod();
         boolean isGet = "GET".equals(method);
         if (isGet || "HEAD".equals(method)) {
            //是否支持last-modified头
            long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
            if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
               return;
            }
         }

         //调用preHandler  拦截器方法
         if (!mappedHandler.applyPreHandle(processedRequest, response)) {
            return;
         }

         // Actually invoke the handler.
         //执行handler 返回modelAndView对象
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

         if (asyncManager.isConcurrentHandlingStarted()) {
            return;
         }
         //由相应RequestToViewNameTranslator 获取getViewName
         applyDefaultViewName(processedRequest, mv);
         //调用postHandler 方法
         mappedHandler.applyPostHandle(processedRequest, response, mv);
      }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值