當前位置:
首頁 > 最新 > druid-spring-boot-starter源碼解析

druid-spring-boot-starter源碼解析

《目錄》

Druid的配置方式純Java代碼創建:基於spring創建:Spring Boot Starterdruid-spring-boot-starter源碼解析小結


Druid的配置方式

druid-spring-boot-starter的源代碼地址託管在github上,Druid是一個開源項目,源代碼倉庫地址是 https://github.com/alibaba/druid 。同時每次Druid發布正式版本和快照的時候,都會把源碼打包,你可以從上面的下載地址中找到相關版本的源碼

其配置方式主要有三種


第二種方式是基於spring創建,以下是一個參考的連接池配置:

通常來說,只需要修改initialSize、minIdle、maxActive。

需要注意的是:

1)如果用Oracle,則把poolPreparedStatements配置為true,mysql可以配置為false。分庫分表較多的資料庫,建議配置為false。

2)removeabandoned不建議在生產環境中打開 .

3)如果用SQL Server,建議追加配置 .

啟用Web監控統計功能需要在Web應用的web.xml中加入這個Servlet聲明 .


最後一種方式,Druid Spring Boot Starter 用於幫助你在Spring Boot項目中輕鬆集成Druid資料庫連接池和監控。

首先,在 Spring Boot 項目中加入druid-spring-boot-starter依賴:

然後添加配置:

接下來進行配置屬性的工作:

Druid Spring Boot Starter 配置屬性的名稱完全遵照 Druid,你可以通過 Spring Boot 配置文件來配置Druid資料庫連接池和監控,如果沒有配置則使用默認值。

JDBC 配置:

連接池配置:

監控配置:

如果是多數劇源的話,添加配置如下:

這裡需要強烈注意:Spring Boot 2.X 版本不再支持配置繼承,多數據源的話每個數據源的所有配置都需要單獨配置,否則配置不會生效。

創建數據源:

目前為以下 Filter 提供了配置支持,

StatFilter

WallFilter

ConfigFilter

EncodingConvertFilter

Slf4jLogFilter

Log4jFilter

Log4j2Filter

CommonsLogFilter

要想使自定義 Filter 配置生效需要將對應 Filter 的 enabled 設置為 true ,Druid Spring Boot Starter 默認會啟用 StatFilter,你也可以將其 enabled 設置為 false 來禁用它。

以上就是對於druid三種使用方式的總結,出於權威性考慮,筆者參考了官方文檔https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter。通過這三種方式的比較,我們很容易發現,第三種方式spring-boot-starter是最簡單的,那麼其實現原理是怎樣的?我們一起進入下一個內容 druid-spring-boot-starter源碼解析。


druid-spring-boot-starter源碼解析

我們首先看一下druid-spring-boot-starter的代碼結構:

首先我們可以一下依賴,作為一款底層中間件,其依賴還是相對比較精簡

我們接下來看到有一個文件additional-spring-configuration-metadata.json,內容如下:

這裡需要解釋一下,這個文件的術語在spring boot里叫做元數據。Spring Boot jar包含元數據文件,提供所有支持的配置屬性的詳細信息。這些文件旨在允許IDE開發人員在用戶使用application.properties 或application.yml文件時提供上下文幫助和「代碼完成」 。主要的元數據文件是在編譯器通過處理所有被@ConfigurationProperties註解的節點來自動生成的。

配置元數據位於jars文件中的META-INF/spring-configuration-metadata.json,它們使用一個具有」groups」或」properties」分類節點的簡單JSON格式。

每個」property」是一個配置節點,用戶可以使用特定的值指定它。例如,server.port和server.servlet-path可能在application.properties中如以下定義:

「groups」是高級別的節點,它們本身不指定一個值,但為properties提供一個有上下文關聯的分組。例如,server.port和server.servlet-path屬性是server組的一部分。

注意不需要每個」property」都有一個」group」,一些屬性可以以自己的形式存在。

groups數組包含的JSON對象可以由以下屬性組成:

properties數組中包含的JSON對象可由以下屬性構成:

deprecation每個properties元素的屬性中包含的JSON對象可以包含以下屬性:

注意在Spring Boot 1.3之前,deprecated可以使用單個布爾屬性來代替deprecation元素。這仍然以不推薦的方式支持,不應再使用。如果沒有理由和替換可用,deprecation應該設置一個空的對象。

值得一提的是,元數據節點是可以重複的。在同一個元數據文件中出現多次相同名稱的」property」和」group」對象是可以接受的。例如,Spring Boot將spring.datasource屬性綁定到Hikari,Tomcat和DBCP類,並且每個都潛在的提供了重複的屬性名。這些元數據的消費者需要確保他們支持這樣的場景。

主要的元數據文件是在編譯器通過處理所有被@ConfigurationProperties註解的節點來自動生成的。

接下來,我們來看spring.factories的內容,如下所示:

簡單的代碼,卻有很多的spring boot註解,我們一一道來。

Spring框架還提供了很多@Condition給我們用,主要功能總結如下:

@ConditionalOnBean(僅僅在當前上下文中存在某個對象時,才會實例化一個Bean)

@ConditionalOnClass(某個class位於類路徑上,才會實例化一個Bean)

@ConditionalOnExpression(當表達式為true的時候,才會實例化一個Bean)

@ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時,才會實例化一個Bean)

@ConditionalOnMissingClass(某個class類路徑上不存在的時候,才會實例化一個Bean)

@ConditionalOnNotWebApplication(不是web應用)

接下來一組是控制執行順序的:

@AutoConfigureAfter:在指定的配置類初始化後再載入

@AutoConfigureBefore:在指定的配置類初始化前載入

@AutoConfigureOrder:數越小越先初始化

EnableConfigurationProperties,在SpringBoot的注釋中是這樣說明的:為帶有@ConfigurationProperties註解的Bean提供有效的支持。這個註解可以提供一種方便的方式來將帶有@ConfigurationProperties註解的類注入為Spring容器的Bean。你之前可能聽說過類似這樣的說法@ConfigurationProperties註解可以生效是因為在SpringBoot中有一個類叫ConfigurationPropertiesAutoConfiguration,它為@ConfigurationProperties註解的解析提供了支持的工作,這種說法更準確一點的說法是在這個類上還存在了@Configuration和@EnableConfigurationProperties這兩個註解。在該案例中,主要是如下兩個類:

SpringBoot 的 @Import 用於將指定的類實例注入之Spring IOC Container中。在這個案例中,我們可以看到DruidDataSourceAutoConfigure注入了DruidSpringAopConfiguration、DruidStatViewServletConfiguration、DruidWebStatFilterConfiguration和DruidFilterConfiguration四個實例,如下圖所示,實際就是代替了之前舊XML模式下Filter等攔截器的bean的初始化工作。

我們接下來重新回歸DruidDataSourceAutoConfigure的源碼,我們可以看到其定義了一個DataSource的BEAN,並且返回了一個DruidDataSourceWrapper包裝類。

我們可以看到這個類繼承了DruidDataSource並且實現了InitializingBean介面。

InitializingBean介面為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是繼承該介面的類,在初始化bean的時候會執行該方法。在spring初始化bean的時候,如果該bean是實現了InitializingBean介面,並且同時在配置文件中指定了init-method,系統則是先調用afterPropertiesSet方法,然後在調用init-method中指定的方法。

這裡有一段小小的總結:

1:spring為bean提供了兩種初始化bean的方式,實現InitializingBean介面,實現afterPropertiesSet方法,或者在配置文件中同過init-method指定,兩種方式可以同時使用

2:實現InitializingBean介面是直接調用afterPropertiesSet方法,比通過反射調用init-method指定的方法效率相對來說要高點。但是init-method方式消除了對spring的依賴

3:如果調用afterPropertiesSet方法時出錯,則不調用init-method指定的方法。

從這個類我們可以看出,該DruidDataSourceWrapper作為核心druid代理datasource類,對於屬性的裝配、filter的引入起到了關鍵的組裝作用。

以上就是全部的druid spring boot starte源碼解析內容,通過這個源碼解析,相信大家可以很清晰的理解其是如何替換了原始的spring xml配置文件,從而簡化了開發者的接入成本。


小結

通過實際配置方案,源碼閱讀,我們可以了解到spring boot starter方式是最簡單的使用方式,也學習了其原理。

就像SPRING官方文檔在https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter所說的那樣:

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.

啟動器Starters是一組方便的依賴關係描述符,您可以將其包含在應用程序中。您可以獲得所需的所有Spring和相關技術的一站式服務,而無需查看示例代碼和複製粘貼依賴描述符的負擔。例如,如果要開始使用Spring和JPA進行資料庫訪問,請spring-boot-starter-data-jpa在項目中包含依賴項。

所以,在寫一些中間件的client時,不妨提供一些spring-boot-starter,讓使用方更加簡單的使用你的產品,也是中間件除了穩定性、高可用等之外,應該追求的方向。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 工匠小豬豬的技術世界 的精彩文章:

TAG:工匠小豬豬的技術世界 |