spring源码-6-springmvc

来源:互联网 发布:经济数据库都有什么 编辑:程序博客网 时间:2024/05/29 15:05

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);      }
0 0