攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解_第1頁
攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解_第2頁
攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解_第3頁
攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解_第4頁
攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解目錄背景加密數(shù)據(jù)源自主實(shí)現(xiàn)流程基礎(chǔ)鞏固額外嘗試啟示錄

背景

SpringBoot項(xiàng)目,使用Druid自動(dòng)裝配的數(shù)據(jù)源,數(shù)據(jù)源的帳號(hào)密碼配置加密后,如何完成數(shù)據(jù)源的裝配呢?

druid-spring-boot-starter雖然自帶了加密配置,但是密鑰也是配置的,如果需要用自定義的加密解密工具,如果不用自帶的工具,怎么自定義實(shí)現(xiàn)加密數(shù)據(jù)源的裝配呢?

本文從DruidDataSourceAutoConfigure類源碼入手,仿造該類,自定義一個(gè)數(shù)據(jù)源注入配置,在真正注入DruidDataSource之前,對(duì)druid配置信息完成解密。

主要思考三個(gè)問題:

自定的Configuration類中的@Bean注入一個(gè)DruidDataSource,為什么比自動(dòng)裝配的時(shí)機(jī)早呢?如果自定義一個(gè)自動(dòng)裝配類,包含DataSourceProperties屬性,對(duì)它的帳號(hào)密碼解密后,讓它在DruidDataSourceAutoConfigure類之前裝配,怎么實(shí)現(xiàn)呢?自動(dòng)裝配類的工作原理是什么?注入優(yōu)先級(jí)怎么確定的?

加密數(shù)據(jù)源自主實(shí)現(xiàn)流程

Notregisteredvia@EnableConfigurationProperties,

markedasSpringcomponent,

orscannedvia@ConfigurationPropertiesScan

@ConfigurationProperties用法限制,我想到一個(gè)解決辦法,為當(dāng)前類加上@Component,同時(shí)制定一個(gè)不可能的注入條件:@ConditionalOnProperty(prefix=xx,name=xxx,havingValue=impossible)。

不用官方的加密插件,自定義Druid的解密配置,我想到的方法是完全仿照Druid數(shù)據(jù)源的自動(dòng)裝配過程,改寫DruidDataSource的注入過程。

關(guān)鍵是修改DataSourceProperties這個(gè)類的實(shí)例的帳號(hào)密碼屬性,其他完全照搬DruidDataSourceAutoConfigure實(shí)現(xiàn)即可。

第一步,由于Druid自動(dòng)注入的數(shù)據(jù)源DruidDataSourceWrapper是一個(gè)包內(nèi)類,不能直接拿來用,所以完全拷貝一份這個(gè)類,定義為咱們自己的數(shù)據(jù)源類:

@Component

@ConfigurationProperties("spring.datasource.druid")

@ConditionalOnProperty(prefix="spring.datasource",name="encrypted",havingValue="impossible")

publicclassMyEncryptedDatasourceWrapperextendsDruidDataSourceimplementsInitializingBean{

@Autowired

privateDataSourcePropertiesbasicProperties;

publicMyEncryptedDatasourceWrapper(){

@Override

publicvoidafterPropertiesSet(){

if(super.getUsername()==null){

super.setUsername(this.basicProperties.determineUsername());

if(super.getPassword()==null){

super.setPassword(this.basicProperties.determinePassword());

if(super.getUrl()==null){

super.setUrl(this.basicProperties.determineUrl());

if(super.getDriverClassName()==null){

super.setDriverClassName(this.basicProperties.getDriverClassName());

@Autowired(

required=false

publicvoidautoAddFilters(ListFilterfilters){

super.filters.addAll(filters);

@Override

publicvoidsetMaxEvictableIdleTimeMillis(longmaxEvictableIdleTimeMillis){

try{

super.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);

}catch(IllegalArgumentExceptionvar4){

super.maxEvictableIdleTimeMillis=maxEvictableIdleTimeMillis;

第二步,自定義一個(gè)DruidDataSourceAutoConfigure類,內(nèi)容與該類一樣,但是多一個(gè)數(shù)據(jù)源配置屬性:

@Configuration

@EnableConfigurationProperties({DruidStatProperties.class,DataSourceProperties.class})

@Import({DruidSpringAopConfiguration.class,DruidStatViewServletConfiguration.class,DruidWebStatFilterConfiguration.class,DruidFilterConfiguration.class})

publicclassMyEncryptedDatasourceWrapperConfig{

*該屬性封裝了spring.datasource屬性,需要對(duì)它的帳號(hào)、密碼屬性進(jìn)行解密

@Autowired

privateDataSourcePropertiesbasicProperties;

*使用數(shù)據(jù)源配置信息,解密帳號(hào)和密碼后創(chuàng)建數(shù)據(jù)庫連接池

*@return

@Bean

publicDataSourcedataSource(){

//TODO對(duì)密碼解密并設(shè)置回去

basicProperties.setPassword(password);

returnnewMyEncryptedDatasourceWrapper();

這樣就完成了Springdruid數(shù)據(jù)源配置的解密處理了。

基礎(chǔ)鞏固

booleanproxyBeanMethods()默認(rèn)值是true.從這個(gè)成員變量的注釋中,我們可以看到一句話Specifywhether{@code@Bean}methodsshouldgetproxiedinordertoenforcebeanlifecyclebehavior,e.g.toreturnsharedsingletonbeaninstancesevenincaseofdirect{@code@Bean}methodcallsinusercode.

其實(shí)從這句話,我們就可以初步得到我們想要的答案了:在帶有@Configuration注解的類中,一個(gè)帶有@Bean注解的方法顯式調(diào)用另一個(gè)帶有@Bean注解的方法,返回的是共享的單例對(duì)象。

參考文檔:《Component和Configuration區(qū)別》

額外嘗試

加密數(shù)據(jù)源配置的解密流程,核心在DataSourceProperties這個(gè)實(shí)例裝配完成后修改密碼信息,嘗試自定義一個(gè)@Configuration中@Bean注入一個(gè)DataSourceProperties實(shí)例,但是這個(gè)對(duì)象到了Druid自動(dòng)注入類那里,屬性還是沒有發(fā)生變化:

@Configuration

@EnableConfigurationProperties(DataSourceProperties.class)

publicclassMyAutoConfig{

@Autowired

privateDataSourcePropertiesbasicProperties;

publicMyAutoConfig(){

System.out.println("MyAutoconfig");

@Bean

publicDataSourcePropertiesbasicProperties(){

//TODO解密配置

System.out.println("username"+basicProperties.getUsername());

returnbasicProperties;

這里@Bean注入生效了,到了DruidDataSource那使用的也是這個(gè)實(shí)例,單步調(diào)試對(duì)象地址是一樣的,但是改的屬性沒有生效。

數(shù)據(jù)源實(shí)例化配置時(shí)引用的屬性:

但是兩個(gè)地方的屬性卻不同,前一步解密的信息并沒有傳遞到真正使用的地方。理論上,同一個(gè)對(duì)象,前面修改了屬性,這里同一個(gè)線程里面,屬性應(yīng)該變化了才對(duì)呢!不得其解。

啟示錄

回顧開頭的三個(gè)問題:

自定的Configuration類中的@Bean注入一個(gè)DruidDataSource,為什么比自動(dòng)裝配的時(shí)機(jī)早呢?因?yàn)锧Bean屬于當(dāng)前項(xiàng)目掃描路徑,它里面的類注入優(yōu)先級(jí)高于第三方j(luò)ar包中的spring.factories的裝配類。如果自定義一個(gè)自動(dòng)裝配類,包含DataSourceProperties屬性,對(duì)它的帳號(hào)密碼解密后,讓它在DruidDataSourceAutoConfigure類之前裝配,怎么實(shí)現(xiàn)呢?嘗試定義一個(gè)裝配類@Bean裝配一個(gè)數(shù)據(jù)源DataSourceProperties對(duì)象,并修改配置。自動(dòng)裝配類的工作原理是什么?注入優(yōu)先級(jí)怎么確定的?spring.factories

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論