關於Spring和SpringMVC的一點感悟
一年前,我們專案最開始使用的SSH(spring+springmvc+hibernate),那時候專案經理搭建好了框架就交給了我們,後來在一次配置事務的過程中,出現了大名鼎鼎的no seesion。
網上查都是說事務沒配置好,我選了好幾種事務配置方法,其中只有註解有效,AOP切面配置事務都報錯。
說實話一開始就走歪了,那時候不理解spring和springMVC的關係,web.xml配置檔案都是這樣:
<!-- 配置Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:config/spring-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置SpringMVC --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:config/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
觀察就會發現,上面的spring配置檔案已經包含了對springMVC配置的檢索,這樣不僅是重複讀取配置檔案的問題還會帶來其它的隱患。
另外一個就是掃描包的範圍配置,spring應該掃描哪些,springMVC應該掃描哪些,或者說應該排除哪些包的掃描。
那次的問題折騰了比較久,記得連續兩個晚上下班回家都在研究,雖然表面看起來是事務的配置問題,如果你老是糾結於事務的配置方法就跑偏了。
我當時就想,為什麼註解沒有問題,而xml配置事務就會報錯,肯定是配置有問題,但是這個事務的配置都是參考網上的,大都是這麼配的。
然後我乾脆在service類中用靜態程式碼塊列印語句,看這個service到底載入了幾次,通過這個方法我發現啟動的過程中一個service列印四次語句,網上查閱配置事務後會生成代理類什麼的,所以列印兩次是沒有問題的,而四次說明這個類重複載入了。
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/springMVC-servlet.xml</param-value>
</init-param>
我把web.xml中springMVC的配置檔案改成上面的樣子,然後在spring掃描包範圍內排除對springMVC的掃描,我還發現事務竟然一部分配置在spring的配置檔案裡,還有一部分配置在springMVC的配置檔案裡,我把它們都移動到了spring配置檔案中,反正就是各種嘗試,目的就是讓service僅僅載入一次。
沒想到最後竟然成功了,現在回憶起當時的那種興奮,不可言狀。但是究竟是什麼原因,我是通過交叉操作,不斷變換配置,才鎖定了問題所在。
總結一下錯誤的原因:
- spring在contextConfigLocation中因為萬用字元問題讀取了springMVC的配置檔案。
- springMVC配置檔案中配置了事務,但是第一次因為是spring直接處理的,它能讀取所有配置檔案,所以即使放在不同的配置檔案裡也能成功。
- 當springMVC再次針對它自己的配置檔案來處理時,只能看到事務的部分配置,所以事務配置不成功,no session !
有一段時間沒用SSH框架了,昨天一個朋友又遇到類似問題,使我想起來了,這裡還是記錄下,以後理解得更透徹了,將會繼續補充。
對於spring和springMVC的整合,我覺得要注意下面幾點:
- 不要太相信網上的東西,很多人只是能跑就行,沒有真正理解。
- 要搞清楚spring和springMVC在一起的時候,各自充當了什麼角色。
- springMVC的配置檔案其實也是依靠spring來解析並做相應處理的。
- 兩者的上下文環境有什麼關係。