成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

[[328499]]

 

本文轉(zhuǎn)載自微信公眾號(hào)「 編程新說(shuō)」,轉(zhuǎn)載本文請(qǐng)聯(lián)系 編程新說(shuō)公眾號(hào)。

解決問(wèn)題的“兩步方針”

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

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

可能有些人會(huì)認(rèn)為第二步是比較難的,其實(shí)非也,第一步才是最難的。我就不解釋了,理解不了的慢慢就會(huì)懂了。

問(wèn)題抽象后也就兩類(lèi)

第一類(lèi),看起來(lái)不復(fù)雜,但是很難解決。

第二類(lèi),看起來(lái)很復(fù)雜,但是較易解決。

和SpringBoot相關(guān)的很多問(wèn)題大抵都屬于第二類(lèi)。

SpringBoot的核心思想

SpringBoot是一個(gè)集成化程度很高的框架,它背后采用的是自動(dòng)配置(autoconfigure)來(lái)實(shí)現(xiàn)的。為了這個(gè)自動(dòng)配置,它引入了條件判斷(Condition)機(jī)制。

這些條件判斷,粗略的分為三類(lèi):

第一類(lèi):對(duì)于application.yml配置文件里的配置屬性進(jìn)行檢測(cè),如果有的話(huà)怎么做,如果沒(méi)有的話(huà)怎么做。

第二類(lèi),對(duì)類(lèi)路徑里面引入的class類(lèi)進(jìn)行檢測(cè),如果有的話(huà)怎么做,如果沒(méi)有的話(huà)怎么做。

第三類(lèi),對(duì)容器中已經(jīng)注冊(cè)的Bean進(jìn)行檢測(cè),如果有的話(huà)怎么做,如果沒(méi)有的話(huà)怎么做。

其實(shí)就相當(dāng)于許多的if/else互相嵌套交織在一起,在SpringBoot啟動(dòng)時(shí),會(huì)逐個(gè)的計(jì)算所有的條件,最終從里面“殺出一條血路來(lái)”。

常用的數(shù)據(jù)庫(kù)訪問(wèn)方案

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

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

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

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

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

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

 

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

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

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

但是實(shí)際情況呢,當(dāng)然是在保證沒(méi)有問(wèn)題的情況下,怎樣簡(jiǎn)單怎樣來(lái)了,只要自己明白自己是在干什么就行了。

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

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

SpringBoot對(duì)于數(shù)據(jù)源的自動(dòng)配置類(lèi)是:

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

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

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

我們注意到每個(gè)類(lèi)上都有四個(gè)注解,來(lái)看下它們的作用:

@Configuration,標(biāo)明這個(gè)類(lèi)會(huì)被Spring框架進(jìn)行處理。

@Conditional,這是一個(gè)條件,需要指定一個(gè)條件類(lèi),這個(gè)條件類(lèi)需要被計(jì)算。

@ConditionalOnMissingBean,這是一個(gè)條件,用來(lái)檢測(cè)指定的Bean的注冊(cè)情況,沒(méi)有被注冊(cè)時(shí)符合條件。

@Import,用來(lái)引入其它類(lèi),被引入的類(lèi)會(huì)被Spring框架進(jìn)行處理。

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

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

  1. @Conditional(PooledDataSourceCondition.class) 

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

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

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

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

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

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

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

  1. @Conditional(PooledDataSourceAvailableCondition.class) 

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

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

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

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

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

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

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

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

@Import引入的類(lèi):

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

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

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

它共包含三個(gè)條件:

@ConditionalOnClass(HikariDataSource.class),表明HikariDataSource這個(gè)類(lèi)必須存在,也就是說(shuō)明要引入Hikari的相關(guān)jar包。

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

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

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

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

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

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

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

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

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

@Conditional(EmbeddedDatabaseCondition.class)

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

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

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

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

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

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

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

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

@Import引入的類(lèi):

  1. @Import(EmbeddedDataSourceConfiguration.class) 

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

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

因?yàn)橐话闱闆r下,我們都使用阿里的Druid數(shù)據(jù)源。

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

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

這里面有兩個(gè)條件:

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

@ConditionalOnMissingBean,表明容器中沒(méi)有被注冊(cè)過(guò)類(lèi)型為DataSource的Bean。

自動(dòng)配置除了和條件有關(guān),還和順序也緊密相關(guān),因?yàn)轫樞蚩壳暗南扔?jì)算條件,一旦條件符合,就會(huì)向容器中注冊(cè)Bean,一旦注冊(cè)了特定類(lèi)型的Bean,后面的可能就沒(méi)有機(jī)會(huì)再注冊(cè)了。

自動(dòng)配置順序:

  1. @AutoConfigureBefore(DataSourceAutoConfiguration.class) 

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

所以,SpringBoot官方的數(shù)據(jù)源自動(dòng)配置再也沒(méi)有機(jī)會(huì)注冊(cè)數(shù)據(jù)源Bean了。這樣我們使用的就是Druid數(shù)據(jù)源了。

 

責(zé)任編輯:武曉燕 來(lái)源: 程新說(shuō)
相關(guān)推薦

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ù)源讀寫(xiě)分離

2020-12-31 07:55:33

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

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ù)源動(dòng)態(tài)切換Spring

2022-12-19 07:21:35

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

2023-10-18 15:25:29

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

2009-06-15 13:24:46

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

2010-12-27 09:59:11

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

2017-07-21 14:50:15

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

2023-11-27 07:33:55

2025-02-05 09:17:40

2017-09-04 14:52:51

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

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美日韩亚洲视频 | 一区二区不卡视频 | 天天爽天天操 | 麻豆一区一区三区四区 | 精品中文字幕久久 | 欧美亚洲高清 | 国产情侣啪啪 | 成人免费在线观看 | 欧美美乳 | 超碰av人人| 人人擦人人 | 国产高清无av久久 | 三级免费毛片 | 国产精品不卡 | 国产欧美日韩综合精品一 | 99reav| 久久夜视频| 自拍偷拍第1页 | 国产精品毛片无码 | 色狠狠一区 | 91精品国产91久久久久久吃药 | 在线伊人 | 亚洲国产成人av | 91精品国产91久久久 | 日韩精品视频网 | 亚洲成人999| 国产亚洲久 | 欧美综合自拍 | 国产高清视频 | 成人亚洲网站 | 性福视频在线观看 | 日韩av在线一区二区 | 黄色在线免费观看视频网站 | 成人一区二区在线 | 国产 亚洲 网红 主播 | 中文字幕第一页在线 | 国产亚洲成av人片在线观看桃 | 国产精品欧美一区二区三区不卡 | 99精品国产一区二区青青牛奶 | 四虎影院一区二区 | 成人国产精品一级毛片视频毛片 |