spring結合資料庫實現策略模式 徹底乾掉if

2021-10-06 19:42:40 字數 4183 閱讀 5444

我們公司是做電子合同系統的,電子合同裡面最重要的就是ca證書,其中頒發機構有浙江ca,湖北ca天威誠信沃通cacfca不同的行業客戶對證書的要求都不一樣,普通的客戶一般用天威誠信或者湖北ca就好,有一些金融客戶,可能會要求必須使用某個ca機構的比如必須要求沃通,為了滿足這個需求,想到了設計模式中的策略模式,不同的客戶在呼叫的時候使用不同的策略就行了。

策略模式是將多個類似的業務公共的部分抽離出來成乙個介面類,然後具體的業務由各自的策略類去實現這個介面,在使用的時候由乙個上下文物件來協調這些業務需要實現的具體策略,上下文物件裡面有個屬性為抽離出來的介面,還有個建構函式,在使用的時候只需要建立

具體策略類,然後把這個類交給上下文,去呼叫相應的策略。

因為涉及客戶動態選擇,所以需要用到資料庫來維護這些關係,我簡單的建立了一下,er圖關係如下

這裡一共建立了四張表,如果只是證書動態選擇可以不用建立服務這個表,我們公司的服務有很多個,比如ca證書,實名認證,時間戳等服務,然後策略表裡面strategy_class是存我們專案中具體策略的實現完整名稱的。然後就是t_user_service_strategy這個表,用來記錄每個使用者每個服務使用的具體策略。

因為是demo我這裡就寫了三個ca機構的策略,反正**寫完以後,後續直接加策略類,然後再資料庫裡面新增一下就好了。然後具體在使用的時候用下面這個**就好。

//查出當前使用者使用的策略

strategys strategys = servicesservice.

getuserservicestrategy

(sid,uid)

;//通過反射得到策略類

identitystrategy identitystrategy =

(identitystrategy) class.

forname

(strategys.

getstrategyclass()

).newinstance()

; strategycontext identitycontext =

newstrategycontext

(identitystrategy)

;//呼叫對應的策略

identitycontext.()

;

這樣好像確實沒啥問題,但因為我們是web專案,不可能不用spring,這些策略類可能會用到spring容器管理的某一下bean,所以我們也需要將這些策略都交給容器去管理,等到想用的時候直接從容器裡面拿就好了,有些同學可能會說這還不簡單,直接加個@component註解不就好了,然後需要用的時候直接通過@autowired注入進來不就好了,但是乙個介面有多個實現類的時候,使用@autowired注入是會有問題的, 別說用啟動的時候就會報異常,具體異常如下:

field identitystrategy in cn.isuyu.dynamic.strategy.controller.indexcontroller required a single bean, but 3 were found:

- hubeicastrategy: defined in file [

/users/fxq/desktop/dynamic-strategy-demo/target/classes/cn/isuyu/dynamic/strategy/strategys/impl/hubeicastrategy.

class

]- wotongcastrategy: defined in file [

/users/fxq/desktop/dynamic-strategy-demo/target/classes/cn/isuyu/dynamic/strategy/strategys/impl/wotongcastrategy.

class

]- zhejiangcastrategy: defined in file [

/users/fxq/desktop/dynamic-strategy-demo/target/classes/cn/isuyu/dynamic/strategy/strategys/impl/zhejiangcastrategy.

class

]action:

consider marking one of the beans as @primary

, updating the consumer to accept multiple beans, or using @qualifier to identify the bean that should be consumed

異常日誌已經說得很明顯了,注入的時候只能有乙個bean,但是發現了三個,然後還給出了解決方案,告訴我們使用@primary註解來設定乙個主要的類,雖然我們在某個類上面加上了@primary註解,啟動不會有問題,但是在使用的時候我們會發現注入的永遠都是那個加了主角的策略類,治標不治本,不符合我們的需求。

@component

public

class

springcontextutils

implements

public

static object getbean

(string name)

/** * 通過該類獲取spring的bean

* @param clazz

* @param * @return

*/public

static

t getbean

(class

clazz)

public

static

t getbean

(string name, class

requiredtype)

public

static

boolean

containsbean

(string name)

public

static

boolean

issingleton

(string name)

public

static class<

?>

gettype

(string name)

}

我們把我們的策略交給容器管理了以後,我們呼叫方式就不能用以前的啦,具體呼叫就成了下面這個樣子啦

strategys strategys = servicesservice.

getuserservicestrategy

(sid,uid)

; class

identitystrategyclass =

(class

) class.

forname

(strategys.

getstrategyclass()

);identitystrategy identitystrategy = springcontextutils.

getbean

(identitystrategyclass)

; strategycontext identitycontext =

newstrategycontext

(identitystrategy)

; identitycontext.()

;

其實我們再儲存資料庫具體策略的時候,完全可以只儲存容器中bean的名字,但是這樣的話如果某一天我們手動給bean加乙個名字,我們通過預設的bean名字就拿不到bean,所以我直接儲存類全名,不管後面怎麼改bean的名稱,只要你不改類的包和類名就行。

遞迴演算法結合資料庫解析成java樹形結構

1 準備表結構及對應的表資料 a 表結構 create table tb tree cid number notnull cname varchar2 50 pid number 父節點 b 表資料 insert into tb tree cid,cname,pid values 1,中國 0 in...

Solr與資料庫結合實現全文檢索

一下給出了乙個簡單的例項展示了如何將solr與資料庫結合實現全文檢索。生產環境下,會有很大差別,這裡的配置僅作為除錯或是開發所用。第一步驟就是安裝jdk 和server 伺服器tomcat,這個也挺簡單,這裡就省略了。將solr自帶的乙個例子複製乙份,我這裡演示的版本是solr最新版本solr 4....

資料庫測試策略

1.資料庫備份 內容正確性 不同介質與空間的備份,備份異常處理 大資料量的備份 部分or全部備份 2.資料庫恢復 備份恢復操作是否正常 恢復過程中對異常情況的處理,不同環境下的恢復 3.資料庫許可權管理 許可權裝置 各許可權分配功能實現 4.檢視測試 測試資料庫檢視定義是否反映了使用者的需求 5.資...