spring mvc 的启动过程

1.一个web的项目启动,从web.xml开始

<web-app>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-context.xml</param-value>
  </context-param>

  <servlet>
    <servlet-name>app</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/app/*</url-pattern>
  </servlet-mapping>

</web-app>

第一步,开启监听,启动WebApplicationContext

org.springframework.web.context.ContextLoaderListener
初始化方法
public void contextInitialized(ServletContextEvent event) {
    super.contextInitialized(event);
}

找其父类
public void contextInitialized(ServletContextEvent event) {
    this.initWebApplicationContext(event.getServletContext());
}
进入initWebApplicationContext方法
if(this.context == null) {
    this.context = this.createWebApplicationContext(servletContext);//创建WebApplicationContext
}
if(this.context instanceof ConfigurableWebApplicationContext) {
    ConfigurableWebApplicationContext err = (ConfigurableWebApplicationContext)this.context;
    if(!err.isActive()) {
        if(err.getParent() == null) {
            ApplicationContext elapsedTime = this.loadParentContext(servletContext);
            err.setParent(elapsedTime);
        }

        this.configureAndRefreshWebApplicationContext(err, servletContext);
    }
}

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
把WebApplicationContext放到servletContext
这边的上下文为Root WebApplicationContext包括serviceImpl,daoImpl

第二步,启动DispatcherServlet,初始化如下:

public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer
public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer
public abstract class AbstractAnnotationConfigDispatcherServletInitializer extends AbstractDispatcherServletInitializer
public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext 


public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    this.registerDispatcherServlet(servletContext);
}

protected void registerDispatcherServlet(ServletContext servletContext) {
    String servletName = this.getServletName();
    Assert.hasLength(servletName, "getServletName() may not return empty or null");
    WebApplicationContext servletAppContext = this.createServletApplicationContext();//创建servletApplicationContext
    Assert.notNull(servletAppContext, "createServletApplicationContext() did not return an application context for servlet [" + servletName + "]");
    DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
    Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);//把 dispatcherServlet放到servletContext里面

    Assert.notNull(registration, "Failed to register servlet with name \'" + servletName + "\'." + "Check if there is another servlet registered under the same name.");
    registration.setLoadOnStartup(1);
    registration.addMapping(this.getServletMappings());
    registration.setAsyncSupported(this.isAsyncSupported());
    Filter[] filters = this.getServletFilters();
    if(!ObjectUtils.isEmpty(filters)) {
        Filter[] var7 = filters;
        int var8 = filters.length;

        for(int var9 = 0; var9 < var8; ++var9) {
            Filter filter = var7[var9];
            this.registerServletFilter(servletContext, filter);
        }
    }

    this.customizeRegistration(registration);
}
protected WebApplicationContext createServletApplicationContext() {//初始化servletApplicationContext上下文
    AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
    Class[] configClasses = this.getServletConfigClasses();
    if(!ObjectUtils.isEmpty(configClasses)) {
        servletAppContext.register(configClasses);
    }

    return servletAppContext;
}
public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext


这边的上下文为servlet的上下文,即controller的上下文


第三步,DispatcherServlet请求处理
public class DispatcherServlet extends FrameworkServlet
{
protected void initStrategies(ApplicationContext context) {//把上下文的数据初始化对象中
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    if(this.logger.isDebugEnabled()) {
        String attributesSnapshot = urlPathHelper.getRequestUri(request);
        String inputFlashMap = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult()?" resumed":"";
        this.logger.debug("DispatcherServlet with name \'" + this.getServletName() + "\'" + inputFlashMap + " processing " + request.getMethod() + " request for [" + attributesSnapshot + "]");
    }

    HashMap attributesSnapshot1 = null;
    if(WebUtils.isIncludeRequest(request)) {
        this.logger.debug("Taking snapshot of request attributes before include");
        attributesSnapshot1 = new HashMap();
        Enumeration inputFlashMap1 = request.getAttributeNames();

        label113:
        while(true) {
            String attrName;
            do {
                if(!inputFlashMap1.hasMoreElements()) {
                    break label113;
                }

                attrName = (String)inputFlashMap1.nextElement();
            } while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet"));

            attributesSnapshot1.put(attrName, request.getAttribute(attrName));
        }
    }

    request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
    request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
    request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
    FlashMap inputFlashMap2 = this.flashMapManager.retrieveAndUpdate(request, response);
    if(inputFlashMap2 != null) {
        request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap2));
    }

    request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
    request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

    try {
        this.doDispatch(request, response);
    } finally {
        if(WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            return;
        }

        if(attributesSnapshot1 != null) {
            this.restoreAttributesAfterInclude(request, attributesSnapshot1);
        }

    }

}

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

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

            try {
                processedRequest = this.checkMultipart(request);
                multipartRequestParsed = processedRequest != request;
                mappedHandler = this.getHandler(processedRequest); //根据条件找到自己mappedHandler

                if(mappedHandler == null || mappedHandler.getHandler() == null) {
                    this.noHandlerFound(processedRequest, response);
                    return;
                }

                HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());//获取HandlerAdapter

                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if(isGet || "HEAD".equals(method)) {
                    long lastModified = ex.getLastModified(request, mappedHandler.getHandler());
                    if(this.logger.isDebugEnabled()) {
                        String requestUri = urlPathHelper.getRequestUri(request);
                        this.logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                    }

                    if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if(!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                try {
                    err = ex.handle(processedRequest, response, mappedHandler.getHandler());
                } finally {
                    if(asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                }

                this.applyDefaultViewName(request, err);//获取viewName
                mappedHandler.applyPostHandle(processedRequest, response, err);
            } catch (Exception var28) {
                dispatchException = var28;
            }

            this.processDispatchResult(processedRequest, response, mappedHandler, err, dispatchException);
        } catch (Exception var29) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, var29);
        } catch (Error var30) {
            this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var30);
        }

    } finally {
        if(asyncManager.isConcurrentHandlingStarted()) {
            mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            return;
        } else {
            if(multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值