spring mvc 的启动过程

来源:互联网 发布:js scroll属性 编辑:程序博客网 时间:2024/06/02 01:23

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