1. 程式人生 > >關於Spring和SpringMVC的一點感悟

關於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僅僅載入一次。

沒想到最後竟然成功了,現在回憶起當時的那種興奮,不可言狀。但是究竟是什麼原因,我是通過交叉操作,不斷變換配置,才鎖定了問題所在。

總結一下錯誤的原因:

  1. spring在contextConfigLocation中因為萬用字元問題讀取了springMVC的配置檔案。
  2. springMVC配置檔案中配置了事務,但是第一次因為是spring直接處理的,它能讀取所有配置檔案,所以即使放在不同的配置檔案裡也能成功。
  3. 當springMVC再次針對它自己的配置檔案來處理時,只能看到事務的部分配置,所以事務配置不成功,no session !

有一段時間沒用SSH框架了,昨天一個朋友又遇到類似問題,使我想起來了,這裡還是記錄下,以後理解得更透徹了,將會繼續補充。

對於spring和springMVC的整合,我覺得要注意下面幾點:

  1. 不要太相信網上的東西,很多人只是能跑就行,沒有真正理解。
  2. 要搞清楚spring和springMVC在一起的時候,各自充當了什麼角色。
  3. springMVC的配置檔案其實也是依靠spring來解析並做相應處理的。
  4. 兩者的上下文環境有什麼關係。