SpringMvc 啓動原理源碼分析

 瞭解一個項目啓動如何實現是瞭解一個框架底層實現的一個必不可少的環節。從使用步驟來看,咱們通常是引入包以後,配置web.xml文件。官方文檔示例的配置以下:java

<web-app>
    <servlet>
        <servlet-name>example</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

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

</web-app>

其實就是把請求引到DispatcherServlet類中去執行。而DispatcherServlet類實際上是一個Servlet類的子類,他的繼承結構以下:web

咱們都知道當項目啓動時,servlet會執行init方法,在HttpServletBean中覆寫了這個init方法。代碼以下spring

@Override    
public final void init() throws ServletException {

if (logger.isDebugEnabled()) { logger.debug("Initializing servlet '" + getServletName() + "'"); } // Set bean properties from init parameters. try {
       
 //獲取servletConfig PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
        //將dispatcherServlet對象封裝到BeanWrapper類裏 BeanWrapper bw
= PropertyAccessorFactory.forBeanPropertyAccess(this);
        //獲取servletContext ResourceLoader resourceLoader
= new ServletContextResourceLoader(getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
        //空的方法 initBeanWrapper(bw); bw.setPropertyValues(pvs,
true); } catch (BeansException ex) { logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); throw ex; } // Let subclasses do whatever initialization they like.
     //這個方法由FrameworkServlet提供實現 initServletBean(); if (logger.isDebugEnabled()) { logger.debug("Servlet '" + getServletName() + "' configured successfully"); } }

 initServletBean();方法由FrameworkServlet類來實現的,而這個方法是初始化SpringMvc的上下文環境。從啓動的打印日誌咱們來分析:(這裏讀取了springmvc.xml還解析了匹配到的類和方法)mvc

信息: Loading XML bean definitions from class path resource [springmvc.xml]
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler
信息: Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/testExcel],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView com.mmc.excel.TestExcelView.testExcel() throws java.io.UnsupportedEncodingException
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/myHandleMethod],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.mmc.hanlemethod.TestHandleMethod.myHandleMethod(org.springframework.web.context.request.WebRequest,org.springframework.ui.Model)
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
信息: Mapped "{[/pets/{petId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public void com.mmc.helloworld.HelloMatrixVariable.findPet2(java.lang.String,int)
三月 26, 2018 11:19:38 上午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod

HttpServletBean類的init方法內執行到initServletBean方法,這個方法被FrameworkServlet類覆寫。這個方法裏其實就一個有效的方法,即initWebApplicationContext();方法。這個方法會調用DispatcherServlet中的onRefresh()方法。而後會執行下面一段內容:app

 

protected void initStrategies(ApplicationContext context) {
     //初始化上傳文件解析器 initMultipartResolver(context);
     //初始化本地解析器 initLocaleResolver(context);
     //主題處理器 initThemeResolver(context);
     //映射處理器 initHandlerMappings(context);
     //處理適配器 initHandlerAdapters(context);
     //異常處理器 initHandlerExceptionResolvers(context);
     //請求到視圖名的翻譯器 initRequestToViewNameTranslator(context);
     //視圖解析器 initViewResolvers(context);
     //初始化FlashManager initFlashMapManager(context); }

我理解的簡單流程:servlet機制先會去獲取web.xml配置文件,獲取到servletConfig和servletContext,(關於servletConfig和context的博文)而後建立webApplicationContext,讀取springmvc.xml,而後初始化適配器,解析器等。框架

另外還有一篇博文是講SpringMvc源碼解析的,寫的很好,很詳細。推薦去看ide

相關文章
相關標籤/搜索