Spring和SpringMVC父子的容器之道---[上篇]


      昨天,給數據組寫接口,不小心掉進坑里掙扎了半天,最后發現是spring和springmvc它們雖是父子但並不和諧,於是在此一記。

       Spring和SpringMVC作為Bean管理容器和MVC層的默認框架,已被眾多WEB應用采用,而在實際開發中,由於有了強大的注解功能,很多基於XML的配置方式已經被替代,但在實際項目中,我們經常會同時配置Spring和SpringMVC的配置文件,分層來管理它們,但是有時候就會出現那么一些奇怪的異常,一旦進坑,讓你無法自拔,就在昨天給數據組寫接口時,我進坑了,就在坑里渾渾噩噩得度分如年,雖然當時很難受很浮躁,但是此刻在總寫這篇博文時我心里是很高興的,真的各位。

       首先,我得幫助大家理解一下父子容器(2個容器)以及它們是如何初始化的,還有就是它們父子如何共享bean資源的。打個比方:老子的資產兒子可以使用,但是兒子的財產老子一般是不使用的;反過來說,Spring父容器中對於SpringMVC子容器中的bean是不可見的,反之,子容器中對於父容器中的bean是可見的。意思就是這個意思,這些概念我也是這倆天才腦補的,以前也沒個正形,各位將就讀讀吧,文章末尾是我專門去給各位扒的美圖,請各位慢用(是關於父子容器中bean的可見性和web容器如何初始化它們的)。

       到這兒,我廢話不多說了,直接給大家把我昨天進坑和出坑的場景簡單描述一下。

       場景一:由父子容器參與的項目中開啟定時任務,由於包掃描的范圍大小,兒子的定時任務失效了?各位他們雖為父子,但是也不和諧啊,你以為是相親相愛一家人資源共享啊,我滴孩啊不是的。在springmvc的核心配置文件中掃描了com.zxz.action包結構,在spring的管理配置文件中首先開啟了掃描定時任務的注解配置<task:annotation-driven />,然后掃描了com.zxz.service包結構,但是沒有觸及到子容器的地盤,這下壞了這蒙在鼓里的我菜鳥,同時開啟倆個世界的定時任務,還在傻傻的打開控制台等着執行呢,但是只有爹的定時任務如願以償,但是兒子的定時任務掛了,.........經過一段時間的糾結,發現了問題,因為它們是2個容器,2個容器啊,不是你在這個容器里配置了,就代表那個容器也會生效啊,不會的,你得分清,爹的是爹的,兒子的是兒子的。

       項目包結構如下:

       service層的定時任務:

1      /**
2      * 開啟Spring容器掃描包范圍內的定時任務
3      */
4     @Scheduled(cron = "0/3 * * * * ? ")
5     public void serviceTask(){
6         System.out.println("Service**********");
7     }    

       controller層的定時任務:

1      /**
2      * 開啟SpringMVC容器掃描包范圍內的定時任務
3      */
4     @Scheduled(cron = "0/6 * * * * ? ")
5     public void webTask(){
6         System.out.println("Controller**********");
7     }  

       兒子的定時任務沒有執行的配置:

1 <!-- task任務掃描注解 -->
2     <task:annotation-driven />
3 
4 <!-- 開啟Spring容器的包掃描 -->
5     <context:component-scan base-package="com.zxz.service"/>

       擴大定時任務掃描的包結構的配置:

1 <!-- task任務掃描注解 -->
2     <task:annotation-driven />
3 
4 <!-- 開啟Spring容器的包掃描 -->
5     <context:component-scan base-package="com.zxz"/>

       場景二:由父子容器參與的項目中加載配置文件中的常量值,由於疏忽導致在父容器的配置文件中沒有配置加載資源文件的那項配置,在service層的代碼中始終沒有獲取到相關常量的值?上面說了,2個容器各自使用各自的。我們在開發中經常有這么一個動作,就是將項目中不變的常量和它們的值都習慣存儲到某個資源文件中,如果在代碼中需要使用它們的值則可以直接獲取,不用再去代碼中查找到對應的常量並修改他們的值,那是愚蠢的做法,極其不方便,聰明人都是會提取出來的為了修改方便維護方便。我這個項目里所有的常量和它們值都放在resource.propertie資源文件里了,但是由於我的忽視,我高看了spring他們一家人的關系,導致我service層的代碼一直報NullPointerException異常,讓我斷點調試卡了半天.......哎,最后發現我沒有在父容器的配置文件中沒有配置加載項,我徹底恍惚了,不知道自己是大意還是菜,總之這些就是一些非常細微的細節,各位。

       controller層和service層同時加載常量(如果使用spring和springmvc來作為容器,則記得同時配置哦):

       父子容器中加載資源文件的配置:

1 <!-- 加載java資源文件 -->
2 <context:property-placeholder location="classpath*:properties/*.propertie"/>

       

       好了各位,我分享的東西暫時就這么多,因為我有把握的就這么多,但是我從網上看到父子容器導致的問題還很多,比如可以讓事務失效啊什么的,菜鳥在進一步探索,如果有結果會給各位准時報告的。如果博文中有什么不對的地方,請留言,我會及時查證並修改的,謝謝各位的捧場(還有別忘了看圖)。

       圖一:父子容器中bean的可見性。                                                       

       圖二:父子容器的初始化情況。

        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM