Struts2.1.6+Spring2.5.6+Hibernate3.3.1全註解實例詳解(二)

  在上一章中詳細分析了JAR包的選擇,那麼這次我將對例子中的一些必須的配置文件進行下說明。雖然這些配置在網上也很容易找到,但是很多都沒有講個因爲所以出來,這樣根本就得不到提高。在此,大象爲各位詳細分析一下這些內容。
    實例中涉及的配置文件有這麼幾個
    applicationContext.xml
    jdbc.properties
    log4j.properties
    struts.xml
    web.xml 
    我準備在本章中只講applicationContext.xmljdbc.propertiesweb.xmllog4j的配置大同小異而且也不在本文範圍。至於struts.xml我準備留到後面與Action代碼一起來講,因爲用的是struts2-convention-plugin插件來實現struts2的註解,所以這兩個結合起來講要好一些。
    第二部分:分析配置文件
    1jdbc.properties
    本例採用MySQL數據庫,所以我設置了一個屬性文件,用來存放一些連接信息和Hibernate相關的設置。

    
因爲我們使用的是Hibernate來與數據庫進行交互,把這些東西寫在單獨的文件裏,是方便修改,如果你想換成SQL Server或是Oracle,只需要更改driverurl以及dialect,而且還可以自由控制sql語句的顯示的開關,非常方便。至於寫在這裏怎麼用呢?請接着看下面的applicationContext.xml說明。
    
2applicationContext.xml
    
這個文件就是spring的主配置文件了,當然,本例也只有這麼一個spring的配置文件,內容不多,但做的工作還是很多的,下面我給大家詳細分析一下。

    我把這兩部分放在一起是因爲這兩者是相互聯繫的,而且也比較好說明。可以這樣來理解,PropertyPlaceholderConfigurer這個類就是讀取jdbc. properties文件,並將它們設置到這個類的屬性中。然後再將下面數據源配置中定義的這些${jdbc.driver}${jdbc.url}字符串換成屬性文件中相同名稱的值。${}這種寫法,是類裏面方法解析用的,網上都說這是叫佔位符,我看了源代碼的,其實是把它們當成字符串截取前後的特殊字符,再根據裏面定義的名稱找屬性文件中對應的值。所以這個類只能讀取properties格式的文件,你如果還有其它需要加入的屬性文件,可以在list之間加入,寫在value標籤裏面。     

    
根據base-package指定的路徑,掃描其下所有包含註解的Bean,並自動注入。比如@Repository@Service這些都是註解,前者表示持久層,後者表示業務層。這可是非常非常好的一個功能,是從Spring2.5開始加入的一個非常棒的特性。有了它,我們將不用再去寫那繁瑣的<bean id="" class="" />。本文的主旨就是全註解,就是爲了告訴大家不用寫配置文件(當然不是絕對不寫)來怎樣進行開發工作。關於這部分的具體情況,在後面代碼章節中會詳細講解。

    
這就是在Spring中定義Hibernate相關的配置,Spring已經集成了這部分功能。通過class裏面定義的類名稱我們很容易就能理解,這是使用註解的方式映射實體以及創建Hiberante SessionFactory${hibernate.dialect}${hibernate.show_sql}和上面的數據源配置獲取方式一樣,當applicationContext.xml定義好之後,就不用再對它進行修改,而是將修改對象變成了jdbc.properties文件。
    
另外在Spring2.5.6版中,加入了一個很有用的小功能,就是packagesToScan屬性,它是根據value中定義的路徑來掃描其下所有的註解實體類。大象對這個路徑做了多種測試,另外又看了源代碼,發現它只能匹配某一類型的路徑,而不是所有路徑。比如上面的value值表示,掃描entity包下面的所有包中的註解類,如果你將類直接放在entity包下,那麼服務器啓動和程序運行時都不會報錯,但是當你的代碼需要用到這個類的時候,就會出現異常,提示你找不到實體。     

    
這是事務定義,而且是使用註解方式定義事務@Transactional),proxy-target-class="true"表示採用動態代理類來管理事務,如果是false表示採用接口代理來管理事務(默認值爲false)。什麼意思呢?就是說對於需要加入事務處理的類,如果是實現接口,那麼將採用Spring的默認事務管理(Spring默認方式爲接口),如果不採用接口,而直接使用類,那麼就需要cglib類庫的支持,它通過動態的創建目標類(就是你需要加入事務的類)的子類,然後對這子類中的方法(當然是從目標類中繼承來的)進行事務管理。這其實就是AOP切面,而且從中可以看出來,需要加入事務的方法不能爲privatestaticfinal 的方法。這樣說也不是很嚴格,說它不能加入事務,是說它不能主動的啓動一個事務,如果某個private方法是被某個public方法調用的,而public方法是可以被動態代理加入事務的,所以這個private方法也一樣被加入了事務,只是它處在public方法的事務之中。但是staticfinal這兩類方法因爲不能被子類覆蓋,所以無法加入事務。如果這兩類型的方法不被其它的事務方法所調用,那麼它們就會以無事務的方式運行,因此很容易造成隱患,這一點請大家特別注意。

    
上面這個就是使用配置式來定義事務,兩種方式的區別主要是,註解式只用寫那麼一句話,然後在業務類或方法中加入@Transactional這個註解標記,就完成事務聲明,不過對於每個業務類都需要在類或方法中加入這些標記。而配置式聲明,就是不用加這些標記,只要你的方法名稱命名比較統一,就可以像上面這樣定義事務規範,然後在aop標籤中定義切入點與執行通知就行了。我感覺如果業務邏輯不是太複雜的情況,配置式會比較簡單,而且修改起來也方便,這兩種方式我都寫出來了,至於用哪一種,由你們自己決定。
    
3web.xml
    
現在使用的Servlet容器還是2.4版,因此web.xml裏面還是需要寫配置文件的,到了3.0版就可以採取註解的方式來實現了。

    Spring ApplicationContext配置文件的路徑,可使用通配符,applicationContext*.xml表示所有以applicationContext開頭的xml文件。多個路徑用,號分隔。比如可以這樣寫:

    
不過推薦採用通配符的寫法,能夠簡單點,爲什麼還要弄那麼複雜呢?
    
context-param是在容器啓動後最先被執行的,並且被放入到容器上下文中。在這裏引入spring的配置文件,是供SpringContextLoaderListener監聽器使用。而這個監聽器中會有一個ContextLoade類用來獲取這個配置文件中的信息。從而進行Spring容器的初始化工作。因爲是採用註解的方式來進行開發,所以spring的配置文件其實只有一個,上面那個星號可以去掉。

    這個監聽器就是爲了讀取Spring的配置文件,這在上面已經講到了。

    
這是Spring提供的一個用來防止內存泄漏的監聽器。在我們使用struts2框架,或其它的某些類庫時,因爲它們自身的設計,會用到Introspector(內省)機制來獲取Bean對象的信息。但不幸的是,這些框架或類庫在分析完一個類之後卻沒有將它從內存中清除掉,內存中還保留有大量的靜態資源,而這些東西又無法進行垃圾回收,因此產生了很嚴重的內存泄漏問題。直接表現爲服務器的內存使用會隨着時間而不斷上升,最後的結果當然就是服務器當掉。所以在這裏加入此監聽器,能夠幫助我們更好的處理內存資源回收的問題。

    
這是Spring的編碼過濾器,我們可以直接拿來用,相信這段配置應該很好理解,不過請大家注意forceEncoding這個參數,把它設置爲true表示不管請求中的編碼是什麼格式,都將強制採用encoding中設置的編碼方式。另外對於響應也將按照encoding指定的編碼進行設置。另外不建議將編碼設置成gb2312或是gbk格式,請採用基於UnicodeUTF-8編碼。

    這個過濾器是個好東西,有了它,我們在使用Hibernate延遲加載的時候,就不會再爲因Session被關閉,導致延遲加載數據異常而頭痛了。網上有很多人說這個不好,其實在使用中,效果還是不錯的。

    
首先我要說這個過濾器的名字很雷,不知道寫這類的傢伙是不是個變態,或者喜歡惡搞。主要原因就是,這個過濾器的功能是推遲清理值棧中的值,以便在web中進行訪問,另外就是爲了配合SiteMesh裝飾器進行工作(官方中的說明)。如果不加這個,那麼Struts2的默認過濾器就會清空值棧中的值,這樣就會導致異常。所以說這類的名字和功能完全不搭邊,很容易讓人產生誤解。

    2.1.6版本里面,已經用這個過濾器取代了以前的FilterDispatcher,而且在api文檔中已經標註爲@deprecated(不贊成),並說明是從Struts 2.1.3版開始就棄用這個過濾器了,改用StrutsPrepareAndExecuteFilter,除此之外,還可以選擇StrutsPrepareFilterStrutsExecuteFilter。不過大象建議大家還是選擇StrutsPrepareAndExecuteFilter吧,這也是官方推薦的。
    web.xml
裏面的幾個重要的配置就這些,不過不要忘了,給這些filter加上filter-mapping映射。還有一點,請注意這些過濾器的順序,這個順序是很重要的,程序運行時,是根據這些filter-mapping的排列順序依次執行過濾操作的。如果不想出現莫名其妙的錯誤,請控制好這些過濾器映射的順序。
    
我會在最後一章附上源碼,大家就這樣慢慢看吧。看到最後一章的時候,可能這些相關的知識就比較清楚了。到時再對照源碼練習下,應該會有一些收穫。恩,這部分就到此結束了,我們下次繼續。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章