1. 程式人生 > >帶著新人學springboot的應用01(springboot+mybatis+快取 下)

帶著新人學springboot的應用01(springboot+mybatis+快取 下)

  springboot+mybatis+快取,基本的用法想必是會了,現在說一說內部大概的原理。

  稍微提一下mybatis,只要匯入了mybatis的依賴,那麼有個自動配置類就會生效,你可以去mybatis的jar包裡面的META-INF/spring.factories中看到這個xxxAutoConfiguration,就如下圖所示,這個應該很熟悉了,所以我們要看看mybatis的配置,肯定要看這個類。

  開這個類,看到這裡

  看了看,其他的沒什麼說的,要看看在yml給mybatis可以配置哪些引數,就去這個類MybatisProperties看看有哪些屬性就ok了,用起來也是很容易。

  接下來看看比較有趣的地方,看看快取的原理。

快取原理

肯定又是自動配置類,ctrl+N搜尋一個CacheAutoConfiguration

  我們要看看這個@Import匯入了什麼元件,點開這個類,打個斷點除錯一下

  除錯之後可以看到就是載入了一些xxxCacheConfiguration,有沒有發現其中有一個是EnCacheCacheConfiguration,還有一個是RedisCacheConfiguration,不就是encache快取,redis快取嘛!即使沒用過,名字應該聽過吧,所以我們大概猜想一下,這是不是springboot提供的針對每個做快取的公司做出來產品的配置類,只要我們匯入相關的依賴,這些配置類就能夠生效?

  可以測試一下我們用的是哪一個,在yml檔案中,加入一個配置debug:true,然後啟動應用,可以看到所有配置類的列印日誌

  下圖所示,說明預設的是用這個快取配置類,當然你還可以看看其他的快取配置類沒有生效

  說明springboot預設用的快取配置類是SimpleCacheConfiguration,那我們來看看載入成功的這個快取配置類,只要弄清楚這個,其他的肯定都差不多

       開啟SimpleCacheConfiguration這個類

  我們看看快取管理器裡有什麼;

  回憶一下我上節說的,CacheManager負責哪個快取公司做的產品,Cache表示這個快取產品裡面很多小空間並且我們要為它取個名字(從下圖看,其實就是名字代表String,小空間就是Cache),而我們要存的鍵值對就是放在小空間裡(Cache),由此可以大概推出Cache裡面就是存放鍵值對的(潛臺詞就是Cache就是一個map)

  ok,其實現在我們已經推斷出來了所謂的快取就是一個map,這個map裡又嵌套了一個map,類似這樣的Map<String,Map<key,value>>結構,接下來,我們繼續看看原始碼(後面我所說的快取其實對應這裡就是Map<key,value>,這個東西等價於我前面提到的Cache,小空間)。

  我們還可以看看是怎麼根據key找到值,還有怎麼將方法的返回值丟到快取裡去

  看到這裡,不知道大家是否大概對快取有了一個本質的瞭解了,不要把快取想得多麼複雜,說破天了不就是一個map嘛!

  其實那些快取公司提供給我們用的就是一個Map<String,Map<key,value>>,其中通過很牛的演算法,讓我們用起來很流暢的這麼一個東西。而且,我們用快取的話,肯定要先指定那個String啊(可以指定多個哦,比如@Cacheable(cacheName={“name1”,“name2”}),不要不會用map了!!!),然後就是通過key(預設就是用方法裡的引數作為key)去找到對應的value,這個value就是我們第二次以及之後查詢需要從從快取裡拿到的資料。

  我應該說的比較詳細了,我大概總結一下:啟動springboot-------->容器裡沒有快取管理器,CacheAutoConfiguration才起作用---------->自動配置類有個註解@Import,匯入了一個xxxSelector,這個xxxSelector向容器裡匯入很多的快取配置類(其實預設起作用的就是SimpleCacheConfiguration)------------>SimpleCacheConfiguration配置類中向容器裡丟進去一個快取管理器-------------->這個快取管理器內部其實就是一個Map<String,Cache>----------->第一次根據String去獲取Cache,Cache為null,建立一個Cache,Cache是一個Map<key,value>----------------->執行service中的方法,返回值放進去這個Map<key,value>中,其中key是service內方法的形參(這裡注意,後面我會說一說怎麼將形參按照一定的規則包裝成一個key的)-------------->第二次查詢,首先根據String去找到對應的Cache,返回Cache,然後根據形參生成一個key,到上面的lookup方法去拿到資料,返回,結束。

小知識補充:

前面一直說按照一定的規則生成key,但是具體什麼規則呢?我們就來看看。

    第一種:我們自己指定的例如@Cacheable(key="#id"),就是指定形參id作為key,這裡支援sSpEL表示式,假如方法的返回值是物件student,可以寫成@Cacheable(key="#result.id"),這是也是將返回結果的id作為key,具體的SpEL表示式可以自己查查資料學習。

  第二種:springboot預設的,我們在哪裡看呢?

  使用斷點除錯 

  假如有興趣自己去除錯的小夥伴,可以參照一下我除錯的位置,我把我除錯的斷點位置放出來:

斷點位置

  等到找到下圖這個方法

  ok,這斷點位置就是這幾個,除錯啟動springboot,在瀏覽器輸入url,就會自己進入除錯介面,你就慢慢點就ok了。

  本來還要說點東西的,emmmm....篇幅太長了,估計還要往後拖了。。。。