選單

我給SpringBoot提了個issue,被採納了…

事情是這樣的

專案中使用了springboot + spring data redis,但是公司規定,redis密碼一律託管,只能遠端獲取。

開發環境使用的單例項redis,連線池用的是lettuce,同事的是實現是把Spring Data Redis自動裝載的程式碼copy一份搬到專案裡,原因從下面的分析中可以看出,Spring相關配置核心類都是包可見的,在外部根本無法繼承和引用。

但是,好事者,也就是在下,覺得這“不夠Spring”,於是,深挖了一番,並在一番分析之後,給社群提了一個比較中肯的Issue,並且被採納。

Spring Data Redis 自動裝配機制

在中有, 其透過依賴於

繼承自,核心程式碼如下

從中可以看出,Spring boot 自動裝配Lettuce連線工廠的條件如下

① 存在 , 中自帶的redis 客戶端類

② 專案中使用配置 為

③ 專案程式碼中只要不定義 , 便會自動按照配置檔案建立

其中,包含兩處關鍵,

建構函式 出現的 和兩個,並且呼叫了父類建構函式

中包含兩個重要方法 和 , 其中 主要處理Pool連線池的相關配置,不做贅述,從下面的分析也可以知道,其實就是,重點看

下面,逐個解析這些關鍵點。

父類建構函式

理解這段程式碼的關鍵是, 其實你如果細心留意,你會發現,Springboot的程式碼,特別是建構函式,大量的用到

關於 ,  可以簡單聊兩句 Spring 4。3的一些改進

當構造方法的引數為單個構造引數時,可以不使用@Autowired進行註解

比如,上面這段程式碼是spring 4。3之後的版本,不需要 也可以正常執行。

同樣是在Spring 4。3版本中,不僅隱式的注入了單構造引數的屬性,還引入了介面。

從原始碼註釋中可以得知,介面是介面的擴充套件,專門為注入點設計的,可以讓注入變得更加寬鬆和更具有可選項。

其中,由可見,當待注入引數的Bean為空或有多個時,便是發揮作用的時候。

如果注入例項為空時,使用則避免了強依賴導致的依賴物件不存在異常

如果有多個例項,的方法會根據Bean實現的介面或註解指定的先後順序獲取一個, 從而了提供了一個更加寬鬆的依賴注入方式

回到,這個父類建構函式本身,其實就是實現這樣的功能:如果使用者提供了和 , 會在建構函式中載入進來,而則比較簡單,就是redis的相關配置。

從配置中讀取redis的相關配置,最簡單的單機redis配置的是簡單的屬性,sentinel是哨兵相關配置,cluster是叢集相關配置,Pool是連線池的相關配置

小結一下,目前,我們可以看到依賴於配置類, 其建構函式讀取了使用者定義的redis配置,其中包含 單機配置+叢集配置+哨兵配置+連線池配置,其中叢集配置和哨兵配置是兩個允許使用者自定義的Bean。

中實現連線池的方法中呼叫了, 其實現如下

其實就是依次讀取哨兵的配置,叢集的配置 以及 單機的配置,如果有就建立連線池返回。

其中 和 是父類的方法,其實現如下,

從中,我們可以知道,其優先讀取在建構函式中由引入的可能存在的使用者自定義配置Bean,如果沒有,再透過讀取完成裝配。

但是,細心的讀者要問了,How about 單機配置?

我給SpringBoot提了個issue,被採納了…

是的,你沒有看錯,單身狗不配……

我給SpringBoot提了個issue,被採納了…

總結起來就是,在建構函式中獲取合適的配置bean,然後在建立連線池的方法裡面查詢,如果沒有就用配置檔案構造一個,但是不支援單例項的redis。

提一個issue吧

保護單身狗,人人有責,於是,我以“單身狗保護協會”的名義給SpringBoot社群提了一個issue

我給SpringBoot提了個issue,被採納了…

然後,大佬回覆,可以保護可以支援,很開心。

其中,有提到使用的方法去改寫的配置,中途我有想到,所以把issue關了,沉吟一陣,覺得不優雅,不開心,又把issue給打開了,很感謝開源團隊的支援和理解,備受鼓舞。