1. 程式人生 > >Spring MVC 在啟動的時候是怎麼初始化其特有的類的

Spring MVC 在啟動的時候是怎麼初始化其特有的類的

昨天重新看了一遍Spring的原始碼,著重看了一下Spring MVC對請求引數的解析部分,但是發現如果要對這塊有更好的理解首先要先明白SpringMVC所特有的一些類(比如)是怎麼初始化的

這裡我只是說一下初始化流程,具體的程式碼就不說了(太詳細可能我也說不出來大笑),只是做個備註:

因為我們一般在web.xml中配置DispatcherServlet的時候load-on-startup設定為立即執行,那麼在容器啟動後(即Spring初始化完成後),那麼執行servlet的init方法進入SpringMVC初始化入口:


這裡的this直接指向HttpSerletBean.init方法

接著,呼叫子類FrameworkServlet的initServletBean()方法:


可以看到這裡初始化了WebApplicationContext亦即SpringMVC的容器,我們看一下在容器初始化的時候做了哪些工作(FrameworkServlet.initWebApplicationContext());


接著進入createWebApplicationContext(rootContext);


可以看到這裡初始化了一個XmlWebApplicationContext的例項,並通過configureAndRefreshWebApplicationContext(wac)方式對該例項進行一些設定:


注意標黃的那個Listener,後面再refresh的執行過程中會呼叫該listener的onApplicationEvent方法,接下來執行wac.refresh()方法:


可以看到這裡做了一些列的操作,包括事件廣播初始化、註冊事件以及最後的釋出事件

AbstractApplicationContext.publicEvent:


通過SimpleApplicationEventMulticaster釋出事件


執行監聽器:


這裡執行的監聽器包括所以在spring中宣告的ApplicationListener例項(猜測),當然也包括剛才的那個SourceFilteringListener監聽器:


在執行監聽器SourceFilteringListener的過程中,該類通過一系列的delege模式最終執行到FrameworkServlet的內部類ContextRefreshListener的onApplicationEvent方法:





可以看到,在initStrategies方法中就出現了初始化HandlerAdapter和HandlerMapping的方法,而我們常用的RequestMappingHandlerAdapter和RequestMappingHandlerMapping都直接或者間接的實現了InitializingBean介面,而這個介面唯一的實現方法afterPropertiesSet是在所有bean初始化後執行,那麼我們看一下這兩個類中的afterPropertiesSet中各自實現了什麼:

RequestMappingHandlerAdapter:


可以看到,HandlerAdapter的afterPropertiesSet初始化了引數及返回值的解析類

HanlderMapping


而HandlerMapping則是註冊所有的HandlerMethod。

看了一遍程式碼才知道,原來Spring在初始化的時候做了這麼多時期,也知道了原來引數解析器和返回值解析器實在監聽器執行的過程中通過HandlerAdapter的afterPropertiesSet方法實現的。通過這麼一次程式碼的閱讀加深了我對springmvc的理解,以後還是要抽時間多看一下原始碼的。