自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot多數(shù)據(jù)源問題打破沙鍋講到底

開發(fā) 架構(gòu)
SpringBoot是一個集成化程度很高的框架,它背后采用的是自動配置(autoconfigure)來實現(xiàn)的。為了這個自動配置,它引入了條件判斷(Condition)機制。

[[328499]]

 

本文轉(zhuǎn)載自微信公眾號「 編程新說」,轉(zhuǎn)載本文請聯(lián)系 編程新說公眾號。

解決問題的“兩步方針”

第一步,將現(xiàn)有狀況徹底搞清楚。

第二步,結(jié)合實際情況和現(xiàn)有狀況給出方案。

可能有些人會認為第二步是比較難的,其實非也,第一步才是最難的。我就不解釋了,理解不了的慢慢就會懂了。

問題抽象后也就兩類

第一類,看起來不復雜,但是很難解決。

第二類,看起來很復雜,但是較易解決。

和SpringBoot相關的很多問題大抵都屬于第二類。

SpringBoot的核心思想

SpringBoot是一個集成化程度很高的框架,它背后采用的是自動配置(autoconfigure)來實現(xiàn)的。為了這個自動配置,它引入了條件判斷(Condition)機制。

這些條件判斷,粗略的分為三類:

第一類:對于application.yml配置文件里的配置屬性進行檢測,如果有的話怎么做,如果沒有的話怎么做。

第二類,對類路徑里面引入的class類進行檢測,如果有的話怎么做,如果沒有的話怎么做。

第三類,對容器中已經(jīng)注冊的Bean進行檢測,如果有的話怎么做,如果沒有的話怎么做。

其實就相當于許多的if/else互相嵌套交織在一起,在SpringBoot啟動時,會逐個的計算所有的條件,最終從里面“殺出一條血路來”。

常用的數(shù)據(jù)庫訪問方案

基于SpringBoot最常用的方案從底向上分為:

最底部一層,數(shù)據(jù)庫,如MySQL

倒數(shù)第二層,數(shù)據(jù)源,就是DataSource

倒數(shù)第三層,事務管理器,就是TransactionManager

倒數(shù)第四層,就是ORM框架,如MyBatis

倒數(shù)第五層,就是分頁組件,如PageHelper

 

如果數(shù)據(jù)庫只有一個,那數(shù)據(jù)源也就是單一數(shù)據(jù)源,事務自然也就是本地事務。

如果數(shù)據(jù)庫有多個,那數(shù)據(jù)源也就變成了多數(shù)據(jù)源,事務自然也變成了分布式事務。

按照微服務的理論,同一份代碼是不會直接訪問到其它數(shù)據(jù)源的,應該是通過接口去訪問其它數(shù)據(jù)源里的數(shù)據(jù)。

但是實際情況呢,當然是在保證沒有問題的情況下,怎樣簡單怎樣來了,只要自己明白自己是在干什么就行了。

SpringBoot官方支持的數(shù)據(jù)源

想要了解一個東西,最好的資料就是官方文檔。想要深入的了解一個東西,恐怕只能看源碼了。

SpringBoot對于數(shù)據(jù)源的自動配置類是:

  1. org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 

默認支持兩種類型的數(shù)據(jù)源的配置:內(nèi)嵌數(shù)據(jù)庫(EmbeddedDatabaseConfiguration)和池化數(shù)據(jù)源(PooledDataSourceConfiguration)。

這兩種數(shù)據(jù)源到底會選擇誰,還要看各自條件的計算結(jié)果,看誰的條件會滿足。

我們注意到每個類上都有四個注解,來看下它們的作用:

@Configuration,標明這個類會被Spring框架進行處理。

@Conditional,這是一個條件,需要指定一個條件類,這個條件類需要被計算。

@ConditionalOnMissingBean,這是一個條件,用來檢測指定的Bean的注冊情況,沒有被注冊時符合條件。

@Import,用來引入其它類,被引入的類會被Spring框架進行處理。

可以看到共有兩個條件,下面來看看這兩種數(shù)據(jù)源配置的具體條件分別是什么。

池化數(shù)據(jù)源的條件一:

  1. @Conditional(PooledDataSourceCondition.class) 

可以看到指定的條件類是PooledDataSourceCondition,該類內(nèi)容如下:

可以看到它繼承自AnyNestedCondition類,意思是這個類的條件依賴于它的內(nèi)部嵌套類的條件,因此它就定義了兩個內(nèi)部嵌套類,而且每個嵌套類上都有條件注解。

內(nèi)部嵌套類一的條件是:

  1. @ConditionalOnProperty(prefix = "spring.datasource"name = "type"

這是關于application.yml配置文件里的屬性的檢測,如果配置了spring.datasource.type這個屬性,則該條件就是符合的,否則就是不符合的。

這個條件的意思就是,是否顯式指定了數(shù)據(jù)源的類型。日常開發(fā)中一般都不指定這個,所以這個條件一般情況下是不符合的。

內(nèi)部嵌套類二的條件是:

  1. @Conditional(PooledDataSourceAvailableCondition.class) 

這又指定了一個條件類,PooledDataSourceAvailableCondition,該類的相關內(nèi)容如下:

它的核心思想是通過類加載器去分別加載下面三個數(shù)據(jù)源類:

  1. com.zaxxer.hikari.HikariDataSource 
  2. org.apache.tomcat.jdbc.pool.DataSource 
  3. org.apache.commons.dbcp2.BasicDataSource 

如果能有一個加載成功的,那么此條件就是符合的。一般情況下我們都不使用這三個數(shù)據(jù)源,所以一般情況下此條件是不符合的。

一般情況下,這兩個嵌套類的條件都是不符合的,所以它們的外部類的條件一般情況下也是不符合的。

池化數(shù)據(jù)源的條件二:

  1. @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) 

這個條件就是檢測Spring的容器里是否注冊了類型為DataSource或XADataSource的Bean,沒有注冊就是符合,這要根據(jù)實際情況了。

@Import引入的類:

  1. @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, 
  2.  
  3. DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, 
  4.  
  5. DataSourceJmxConfiguration.class }) 

可以看到這些引入的類就是每種數(shù)據(jù)源的配置或注冊類了。這里共引入五個類,它們也都是帶有條件的,也會被按順序計算,最多只會有一個符合,或者都不符合。

下面來看一個SpringBoot官方推薦的數(shù)據(jù)源,Hikari的配置,它的內(nèi)容如下:

它共包含三個條件:

@ConditionalOnClass(HikariDataSource.class),表明HikariDataSource這個類必須存在,也就是說明要引入Hikari的相關jar包。

@ConditionalOnMissingBean(DataSource.class),表明DataSource類型的Bean不存在,即截止到目前還沒有注冊過數(shù)據(jù)源。

  1. @ConditionalOnProperty(name = "spring.datasource.type"

havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true),表明指定了數(shù)據(jù)源的類型是Hikari,但是如果沒有指定的話也認為是符合的。

如果這三個條件都符合,就會往容器里注冊一個HikariDataSource類型的數(shù)據(jù)源Bean。

@ConfigurationProperties(prefix = "spring.datasource.hikari")的作用就是,在這個數(shù)據(jù)源Bean實例化時,把application.yml配置文件里以spring.datasource.hikari開頭的配置屬性,都按setter的規(guī)則設置給這個數(shù)據(jù)源Bean實例。

其它類型的數(shù)據(jù)源的注冊細節(jié)和這個Hikari是一模一樣的,所以上述引入的五個數(shù)據(jù)源配置類的條件都會被計算一邊,但是最多只會有一個配置類的條件是符合的。

因此,從某種意義來說,SpringBoot的條件在某種情況下不具有“短路”的特性。

池化數(shù)據(jù)源的部分已經(jīng)講完了。再來看看內(nèi)嵌數(shù)據(jù)源。

內(nèi)嵌數(shù)據(jù)源條件一:

@Conditional(EmbeddedDatabaseCondition.class)

這里指定的條件類是EmbeddedDatabaseCondition,它的相關內(nèi)容如下:

它的核心思想就是,先去判斷看池化數(shù)據(jù)源的條件是否符合,如果池化數(shù)據(jù)源符合的話,那內(nèi)嵌數(shù)據(jù)源肯定是不符合的,因此池化數(shù)據(jù)源的優(yōu)先級高。

然后再去分別加載下面三個內(nèi)嵌數(shù)據(jù)源類:

  1. org.h2.Driver 
  2.  
  3. org.apache.derby.jdbc.EmbeddedDriver 
  4.  
  5. org.hsqldb.jdbcDriver 

只要有一個加載成功,就算是符合。實際當中一般很少使用內(nèi)嵌數(shù)據(jù)源,所以這個條件一般情況下是不符合的。

內(nèi)嵌數(shù)據(jù)源條件二:

  1. @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) 

這個想必都已經(jīng)知道是什么意思了,就是如果此時容器中還沒有注冊數(shù)據(jù)源類型的Bean,那就符合。

@Import引入的類:

  1. @Import(EmbeddedDataSourceConfiguration.class) 

由于內(nèi)嵌數(shù)據(jù)源一般開發(fā)中很少使用,所以就不再看了。

其實一般情況下,SpringBoot官方默認支持的三種池化數(shù)據(jù)源和三種內(nèi)嵌數(shù)據(jù)源的這些條件都是不會符合的。

因為一般情況下,我們都使用阿里的Druid數(shù)據(jù)源。

阿里的Druid數(shù)據(jù)源

Druid數(shù)據(jù)源的自動配置內(nèi)容如下:

這里面有兩個條件:

@ConditionalOnClass(DruidDataSource.class),表明DruidDataSource類需要存在,即已經(jīng)引入了Druid數(shù)據(jù)源的jar包。

@ConditionalOnMissingBean,表明容器中沒有被注冊過類型為DataSource的Bean。

自動配置除了和條件有關,還和順序也緊密相關,因為順序靠前的先計算條件,一旦條件符合,就會向容器中注冊Bean,一旦注冊了特定類型的Bean,后面的可能就沒有機會再注冊了。

自動配置順序:

  1. @AutoConfigureBefore(DataSourceAutoConfiguration.class) 

表明Druid數(shù)據(jù)源的自動配置先于SpringBoot官方的數(shù)據(jù)源自動配置進行,因此Druid數(shù)據(jù)源往容器里注冊了類型為DataSource的Bean。

所以,SpringBoot官方的數(shù)據(jù)源自動配置再也沒有機會注冊數(shù)據(jù)源Bean了。這樣我們使用的就是Druid數(shù)據(jù)源了。

 

責任編輯:武曉燕 來源: 程新說
相關推薦

2024-10-30 10:22:17

2023-09-07 08:39:39

copy屬性數(shù)據(jù)源

2023-06-07 08:08:37

MybatisSpringBoot

2023-01-04 09:33:31

SpringBootMybatis

2020-03-13 14:05:14

SpringBoot+數(shù)據(jù)源Java

2020-11-24 09:56:12

數(shù)據(jù)源讀寫分離

2020-12-31 07:55:33

spring bootMybatis數(shù)據(jù)庫

2025-04-14 01:00:00

Calcite電商系統(tǒng)MySQL

2009-08-14 10:26:27

ibatis多數(shù)據(jù)源

2023-10-31 07:52:53

多數(shù)據(jù)源管理后端

2022-05-18 12:04:19

Mybatis數(shù)據(jù)源Spring

2022-05-10 10:43:35

數(shù)據(jù)源動態(tài)切換Spring

2022-12-19 07:21:35

Hutool-db數(shù)據(jù)庫JDBC

2023-10-18 15:25:29

數(shù)據(jù)源數(shù)據(jù)庫

2017-07-21 14:50:15

數(shù)據(jù)庫DB分庫事務處理

2023-11-27 07:33:55

2010-12-27 09:59:11

ODBC數(shù)據(jù)源

2009-06-15 13:24:46

JBoss數(shù)據(jù)源

2025-02-05 09:17:40

2017-09-04 14:52:51

Tomcat線程數(shù)據(jù)源
點贊
收藏

51CTO技術棧公眾號