iBATIS延遲加載

     所謂的延遲加載,就是將暫時不需要的對象不真正的載人內存,直到真正需要的時候再去執行加載動作。在iBatis中,實現延遲加載的思路:如果一個對象的某個屬性需要被延遲加載,那麼首先創建這個屬性對應的代理對象並返回;當真正使用時,調用這個代理對象的相關方法,invoke方法得以執行,此時,在invoke方法裏面,去執行真正的加載操作。

     總結起來,對於延遲加載,首先創建一個被延遲加載對象的代理對象,當使用代理對象時,就是真正需要加載的時刻,在執行invoke方法時執行加載。

     在iBatis中,延遲加載相關的類主要有:ResultLoader,LazyResultLoader,EnhancedLazyResultLoader。其中ResultLoader是執行數據加載的類,LazyResultLoader和EnhancedResultLoader是延遲加載的的實現類,LazyResultLoader使用的是java的代理模型,EnhancedResultLoader使用的是cglib。

     那麼,在iBatis中,延遲加載是如何實現的呢?

     在iBatis中,在RowMap中,如果某個result屬性中指定了select屬性,那麼此處就有可能會發生延遲加載。在處理ResultMap時,ResultMap類中的getNestedSelectMappingValue方法會觸發ResultLoader的loadResult方法。下面,就先看一下loadResult是如何實現的。

      在上述代碼中,根據setting中指定的enhancementEnabled和lazyLoadingEnabled屬性來決定是否使用延遲加載以及使用延遲加載的策略,分別創建了LazyResultLoader和EnhancedLazyResultLoader對象,並且調用了loadResult方法,下面就分別看一下這兩個類中的loadResult是如何實現的。

     首先看一下LazyResultLoader的loadResult實現

    根據上述代碼可知,使用基於java反射的延遲加載實現,只會延遲加載那些類型爲Collection的屬性,其他屬性即使配置爲延遲加載也會被立即載入內存的。

    然後看一下EnhancedLazyResultLoader的loadResult實現。

   根據上述代碼可知,採用了cglib創建代理對象的技術,而且被延遲加載的屬性類型與LazyResultLoader中不同。如自定義類型的屬性,在LazyResultLoader中不會被延遲加載,在EnhancedLazyResultLoader中會被延遲加載。究其根本原因在於:Java反射代理只能代理接口對象,而cglib的代理對象是基於asm的字節碼增強技術,可以代理接口和對象。

   在創建完了代理對象後,就是當請求真正發生時,代理對象如何處理?如何加載所需數據?下面就來看一下代理對象的invoke方法。

  

     經過上述的講解,結合代碼,可以比較深入的理解iBATIS延遲加載的實現機制。下面對以上內容做一個簡短的總結:

     延遲加載的核心思想是動態代理模式。首先並不加載數據,而是創建一個代理對象,需要數據的時候由代理對象去加載所需數據。iBatis中有兩種延遲加載的方法:基於java反射的LazyResultLoader和基於cglib的EnhancedLazyResultLoader。由於二者實現代理的機制不同,所以對延遲加載的支持也不相同。LazyResultLoader只能延遲加載Collection類型的屬性,而EnhancedLazyResultLoader可以延遲加載Collection類型的屬性,以及自定義類型的屬性,而且性能方面要由於LazyResultLoader。

 

 

 

 

 

 

 

 

 

 

 

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