spring源码-6-springmvc

xiaoxiao2021-02-28  105

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); }
转载请注明原文地址: https://www.6miu.com/read-66614.html

最新回复(0)