基於渠道 租戶動態載入spring bean

2021-10-24 21:38:26 字數 2507 閱讀 4071

在做saas專案時,我們既想統一介面提供給各端呼叫,又希望各端在通用功能基礎上做差異化定製,並滿足不同租戶做個性化定製的訴求,**層面我想好好設計一下,其中比較關鍵的一步就是如何動態的根據渠道和租戶載入不同的實現,本文將圍繞「統一介面」、「渠道定製」、「租戶定製」方面進行實現。

我們將租戶和渠道抽象出註解用來打標

@retention

(retentionpolicy.runtime)

@target()

public @inte***ce

tenantordertag

邏輯部分基本就是上面定義的優先順序的實現

@slf4j

public

class

tenantbeanfactory

註解* 當前請求的'accesschannel'和'tenantid'必須存在*

* bean載入優先順序由高到低:* 1.accesschannel + tenantid 精確匹配

* 2.accesschannel + '-1' ('-1'是指實現類父級別實現, 未被租戶定製; 非'-1'指租戶定製實現類)

* 3.accesschannel.pc + tenantid

* 4.accesschannel.pc + '-1'

** @param clz

* @param * @return

*/public

static

t tagbean

(class

clz)

,租戶={}"

, accesschannel, tenantid)

; t returnbean =

get(accesschannel, tenantid, clz)

; assert.

notnull

(returnbean, string.

format

("類'%s'未匹配到bean"

, clz.

get******name()

)); log.

info

("渠道租戶定製類匹配到'{}'"

, returnbean.

getclass()

.getsuperclass()

.get******name()

);return returnbean;

}private

static

void

abstractclassonly

(class cls)}

private

static

t get

(integer accesschannel, long tenantid, class

clz)

if(beanmap.

containskey

(key2))if

(beanmap.

containskey

(key3))if

(beanmap.

containskey

(key4)

)return null;

}private

static

mapbeanmap

(class

clz)

else

string key =

beankey

(_channel, _tenant)

; t replaced = beanmap.

put(key, entry.

getvalue()

);if(null != replaced)

}return beanmap;

}private

static string beankey

(integer accesschannel, string tenantid)

}

大家可以基於業務自定義抽象類或介面,編寫實現類,注意實現類必須使用註解打標,而且按渠道和租戶定製時務必保證組合唯一。

我們經常看到的在業務包裝類中使用

// 注入list

@autowired

private list

testservices;

// 或者如下

// 注入map

@autowired

private map

testservicemap;

// 顯示的獲取map

mapgetbeansoftype

(itestservice.

class

);

來載入itestservice介面的所有實現類,再根據實現類打標的型別列舉或者實現介面的gettype獲取到型別資訊,為啥還要費力寫這樣乙個載入bean的工具呢,如果加乙個抽象類或介面,就要再寫一遍上面注入和匹配bean的邏輯,實在是太煩了,tenantbeanfactory可以很好的解決這個問題。

多租戶通用許可權設計 基於casbin

所謂許可權控制,概念並不複雜,就是確認某個操作是否能做,本質上僅僅就是個bool判斷.許可權幾乎是每個系統必不可少的功能,和具體業務結合之後,在系統中往往表現的非常複雜和難於控制,很大部分原因是把許可權和具體業務結合的太過緊密,把業務的複雜度也加入到許可權控制中來了.一直以來,都有個想法,想做一套簡...

基於MonkeyRunner的批量渠道包自動化測試

所以我用monkeyrunner實現了自動過渠道包的簡單小工具。扔多少個apk進去,就自動跑多少個,跑完出log,對比失敗時自動停止。不說了,看 唄。usr bin env monkeyrunner coding utf 8 import time import sys import os from...

Flex裡用IconUtility動態載入Icon

為了減少flex檔案體積,我們可以使用release模式編譯外,一些資源可以在執行時載入run time load rtl 今天閒逛web時,無意發現這個iconutility類包,很好用,能定義icon或者image的source 它的格式如下 iconutility.getclass id,pi...