通過jvm安全上下文實(shí)現(xiàn)緩存的方法和系統(tǒng)的制作方法
【技術(shù)領(lǐng)域】
[0001] 本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,特別是涉及一種通過JVM安全上下文實(shí)現(xiàn)緩存的方 法和系統(tǒng)。
【背景技術(shù)】
[0002] 在現(xiàn)在某些業(yè)務(wù)邏輯復(fù)雜的項(xiàng)目中,例如在游戲數(shù)據(jù)分析產(chǎn)品中,Game對象用于 描述游戲的相關(guān)屬性,如游戲類型,開發(fā)商,終端平臺(tái)等,通過執(zhí)行g(shù)etAccessPermission 函數(shù),能夠獲得當(dāng)前登錄用戶是否具有該游戲的權(quán)限,但是用戶的權(quán)限信息統(tǒng)一被一個(gè)稱 之為"個(gè)人中心"的系統(tǒng)集中管理,因此要獲取用戶的權(quán)限信息,需要通過遠(yuǎn)程調(diào)用"個(gè)人中 心"的方式獲取。假設(shè)現(xiàn)在存在界面的展示需求,需要用列表顯示所有的游戲,但是需要按 照當(dāng)前用戶有無權(quán)限進(jìn)行排序,畢竟將無權(quán)限的游戲放在列表的最上方但是又無法操作, 會(huì)是非常糟糕的產(chǎn)品用戶體驗(yàn)設(shè)計(jì)。為了實(shí)現(xiàn)此需求,一般采用Java自帶的排序功能,設(shè) 置排序算法為根據(jù)用戶的權(quán)限屬性accessPermission來排序,但是如此使用,會(huì)帶來大量 的針對"個(gè)人中心"的網(wǎng)絡(luò)請求,如采用冒泡排序,時(shí)間復(fù)雜度為n2,貝如果有100個(gè)游戲, 則需要請求個(gè)人中心10000次,顯然這是一個(gè)非常大的性能瓶頸。要解決性能問題的關(guān)鍵 在于需要一次從個(gè)人中心獲取到用戶擁有權(quán)限的所有游戲列表(使用T表示),并將該列表 傳遞到用于計(jì)算用戶對特定游戲有無權(quán)限的地方。
[0003] 針對上述應(yīng)用場景,現(xiàn)有技術(shù)一的技術(shù)方案:修改函數(shù)getAccessPermission的 定義,將列表T作為函數(shù)參數(shù)傳入。在調(diào)用函數(shù)之前,先調(diào)用個(gè)人中心得到該列表T,調(diào)用 函數(shù)getAccessPermission時(shí)傳入T。如此方案,最大的問題在于向外暴露了獲取游戲權(quán) 限的實(shí)現(xiàn),破壞了"高內(nèi)聚"?,F(xiàn)有技術(shù)二的技術(shù)方案:列表T采用ThreadLocal的方式傳 遞,而不采用函數(shù)getAccessPermission的參數(shù)傳遞,如此不會(huì)破壞函數(shù)的接口,但是何時(shí) 往ThreadLocal里面設(shè)置值會(huì)是個(gè)問題,只有兩種方案:a):在調(diào)用棧的上層代碼中將列 表T設(shè)置到ThreadLocal中,以及負(fù)責(zé)從ThreadLocal中清除列表T,如此依然對外暴露 了具體實(shí)現(xiàn)邏輯,破壞了 "高內(nèi)聚"。b):在函數(shù)getAccessPermission中將列表T設(shè)置到 ThreadLocal中,如此邏輯倒是被封裝在了getAccessPermission函數(shù)中,沒有對外暴露, 但是何時(shí)從ThreadLocal中清空列表T,無法做到緩存的列表T只在本次請求有效,需求對 應(yīng)的功能無法實(shí)現(xiàn)。
【發(fā)明內(nèi)容】
[0004] 基于上述情況,本發(fā)明提出了一種通過JVM安全上下文實(shí)現(xiàn)緩存的方法和系統(tǒng), 保證功能的同時(shí)而不損失設(shè)計(jì)的高內(nèi)聚、低耦合。
[0005] 為了實(shí)現(xiàn)上述目的,本發(fā)明技術(shù)方案的實(shí)施例為:
[0006] -種通過JVM安全上下文實(shí)現(xiàn)緩存的方法,包括以下步驟:
[0007] 當(dāng)接收到用戶的調(diào)用請求時(shí),使用當(dāng)前登錄用戶對預(yù)設(shè)對象進(jìn)行實(shí)例化,得到所 述預(yù)設(shè)對象的實(shí)例,所述預(yù)設(shè)對象用于緩存用戶業(yè)務(wù)需要的數(shù)據(jù),所述預(yù)設(shè)對象繼承于 Principal對象;
[0008] 將所述實(shí)例注入當(dāng)前調(diào)用堆棧的JVM安全上下文中;
[0009] 在獲取訪問權(quán)限函數(shù)中獲取所述JVM安全上下文中的所述實(shí)例,并查詢所述實(shí)例 中是否緩存當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù);
[0010] 當(dāng)查詢結(jié)果為是時(shí),從所述實(shí)例中獲取所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù);當(dāng)查 詢結(jié)果為否時(shí),從第三方系統(tǒng)獲取所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù),并將所述當(dāng)前登錄 用戶業(yè)務(wù)需要的數(shù)據(jù)緩存在所述實(shí)例中;
[0011] 當(dāng)根據(jù)所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù)完成所述用戶的調(diào)用請求對應(yīng)的業(yè)務(wù) 時(shí),結(jié)束所述當(dāng)前調(diào)用堆棧。
[0012] -種通過JVM安全上下文實(shí)現(xiàn)緩存的系統(tǒng),包括:
[0013] 實(shí)例化模塊,用于當(dāng)接收到用戶的調(diào)用請求時(shí),使用當(dāng)前登錄用戶對預(yù)設(shè)對象進(jìn) 行實(shí)例化,得到所述預(yù)設(shè)對象的實(shí)例,所述預(yù)設(shè)對象用于緩存用戶業(yè)務(wù)需要的數(shù)據(jù),所述預(yù) 設(shè)對象繼承于Principal對象;
[0014] 注入模塊,用于將所述實(shí)例注入當(dāng)前調(diào)用堆棧的JVM安全上下文中;
[0015] 查詢模塊,用于在獲取訪問權(quán)限函數(shù)中獲取所述JVM安全上下文中的所述實(shí)例, 并查詢所述實(shí)例中是否緩存當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù);
[0016] 處理模塊,用于當(dāng)查詢結(jié)果為是時(shí),從所述實(shí)例中獲取所述當(dāng)前登錄用戶業(yè)務(wù)需 要的數(shù)據(jù);當(dāng)查詢結(jié)果為否時(shí),從第三方系統(tǒng)獲取所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù),并將 所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù)緩存在所述實(shí)例中;
[0017] 結(jié)束模塊,用于當(dāng)根據(jù)所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù)完成所述用戶的調(diào)用請 求對應(yīng)的業(yè)務(wù)時(shí),結(jié)束所述當(dāng)前調(diào)用堆棧。
[0018] 與現(xiàn)有技術(shù)相比,本發(fā)明的有益效果為:本發(fā)明通過JVM安全上下文實(shí)現(xiàn)緩存的 方法和系統(tǒng),能夠不破壞函數(shù)接口的前提下進(jìn)行信息傳遞;放在安全上下文中的信息的生 命期自動(dòng)是用戶調(diào)用生命期的;當(dāng)本次用戶請求結(jié)束之后,和當(dāng)前調(diào)用堆棧對應(yīng)的安全上 下文被自動(dòng)銷毀,所以存儲(chǔ)在安全上下文中的實(shí)例,以及實(shí)例中緩存的數(shù)據(jù),也隨之被銷 毀,保證功能的同時(shí)而不損失設(shè)計(jì)的高內(nèi)聚、低耦合,適合實(shí)際應(yīng)用。
【附圖說明】
[0019] 圖1為一個(gè)實(shí)施例中通過JVM安全上下文實(shí)現(xiàn)緩存的方法流程圖;
[0020] 圖2為基于圖1所示方法一個(gè)具體示例中通過JVM安全上下文實(shí)現(xiàn)緩存的方法流 程圖;
[0021]圖3為一個(gè)實(shí)施例中通過JVM安全上下文實(shí)現(xiàn)緩存的系統(tǒng)結(jié)構(gòu)示意圖。
【具體實(shí)施方式】
[0022] 為使本發(fā)明的目的、技術(shù)方案及優(yōu)點(diǎn)更加清楚明白,以下結(jié)合附圖及實(shí)施例,對本 發(fā)明進(jìn)行進(jìn)一步的詳細(xì)說明。應(yīng)當(dāng)理解,此處所描述的【具體實(shí)施方式】僅僅用以解釋本發(fā)明, 并不限定本發(fā)明的保護(hù)范圍。
[0023] -個(gè)實(shí)施例中通過JVM安全上下文實(shí)現(xiàn)緩存的方法,如圖1所示,包括以下步驟:
[0024] 步驟S101 :當(dāng)接收到用戶的調(diào)用請求時(shí),使用當(dāng)前登錄用戶對預(yù)設(shè)對象進(jìn)行實(shí)例 化,得到所述預(yù)設(shè)對象的實(shí)例,所述預(yù)設(shè)對象用于緩存用戶業(yè)務(wù)需要的數(shù)據(jù),所述預(yù)設(shè)對象 繼承于Principal對象;
[0025] 步驟S102 :將所述實(shí)例注入當(dāng)前調(diào)用堆棧的JVM安全上下文中;
[0026] 步驟S103 :在獲取訪問權(quán)限函數(shù)中獲取所述JVM安全上下文中的所述實(shí)例,并查 詢所述實(shí)例中是否緩存當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù);所述獲取訪問權(quán)限函數(shù)可以反復(fù)使 用從第三方系統(tǒng)獲取的數(shù)據(jù);
[0027] 步驟S104 :當(dāng)查詢結(jié)果為是時(shí),從所述實(shí)例中獲取所述當(dāng)前登錄用戶業(yè)務(wù)需要的 數(shù)據(jù);當(dāng)查詢結(jié)果為否時(shí),從第三方系統(tǒng)獲取所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù),并將所述 當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù)緩存在所述實(shí)例中;
[0028] 步驟S105:當(dāng)根據(jù)所述當(dāng)前登錄用戶業(yè)務(wù)需要的數(shù)據(jù)完成所述用戶的調(diào)用請求 對應(yīng)的業(yè)務(wù)時(shí),結(jié)束所述當(dāng)前調(diào)用堆棧。當(dāng)完成對應(yīng)的業(yè)務(wù)時(shí),JVM自動(dòng)結(jié)束當(dāng)前調(diào)用堆棧, 安全上下文,實(shí)例以及被緩存在實(shí)例中的用戶業(yè)務(wù)需要的數(shù)據(jù)均被自動(dòng)銷毀。
[0029] 從以上描述可知,本發(fā)明能夠不破壞函數(shù)接口的前提下進(jìn)行信息傳遞;放在安全 上下文中的信息的生命期自動(dòng)是用戶調(diào)用生命期的;當(dāng)本次用戶請求結(jié)束之后,和當(dāng)前調(diào) 用堆棧對應(yīng)的安全上下文被自動(dòng)銷毀,所以存儲(chǔ)在安全上下文中的實(shí)例,以及實(shí)例中緩存 的數(shù)據(jù),也隨之被銷毀,保證功能的同時(shí)而不損失設(shè)計(jì)的高內(nèi)聚、低耦合。
[0030] 此外,在一個(gè)具體示例中,所述預(yù)設(shè)對象以值對的方式緩存所述用戶業(yè)務(wù)需要的 數(shù)據(jù)。方便后續(xù)進(jìn)行相應(yīng)的擴(kuò)展,滿足更多的應(yīng)用需求。
[0031] 此外,在一個(gè)具體示例中,所述用戶業(yè)務(wù)需要的數(shù)據(jù)包括用戶擁有權(quán)限的列表和/ 或用戶身份標(biāo)識(shí)。根據(jù)實(shí)際需要獲取業(yè)務(wù)需要的數(shù)據(jù),再根據(jù)業(yè)務(wù)需要的數(shù)據(jù)完成相應(yīng)的 業(yè)務(wù)邏輯,適合應(yīng)用。
[0032] 為了更好地理解上述方法,以下詳細(xì)闡述一個(gè)本發(fā)明通過JVM安全上下文實(shí)現(xiàn)緩 存的方法的應(yīng)用實(shí)例。
[0033] 調(diào)用堆棧和安全上下文的定義如下:
[0034] 調(diào)用堆棧:程序的執(zhí)行時(shí)按照一個(gè)函數(shù)調(diào)用另外一個(gè)函數(shù)如此嵌套進(jìn)行的,這樣 的數(shù)據(jù)結(jié)構(gòu)稱之為調(diào)用堆棧或執(zhí)行堆棧(callstack),將此堆棧打印出來的信息大致為:
[0035] Thread,sleep(long)line:notavailable
[0036] AA.d()line:8
[0037] AA.fOline:16
[0038] AA.main(String[]) 1ine: 20
[0039] 通過上面的信息,我們能夠發(fā)現(xiàn)函數(shù)的嵌套調(diào)用過程是:main->f->d->Sle印,當(dāng) 函數(shù)執(zhí)行完成退出時(shí),依次從sleep,d,f,main退出,所以稱此結(jié)構(gòu)為"棧"
[0040] 安全上下文:當(dāng)需要控制代碼的執(zhí)行權(quán)限時(shí),如當(dāng)前用戶能否訪問某個(gè)文件,或是 訪問某個(gè)網(wǎng)頁,處理這些邏輯的代碼都在一個(gè)稱之為"安全上下文"環(huán)境中運(yùn)行。如下代 碼:
[0041 ]
[0042] 如上述有下劃線部分的代碼即在安全上下文的控制范圍之內(nèi)運(yùn)行,這些代碼要能 夠成功執(zhí)行,必須是當(dāng)前上下文中的用戶對一定的文件權(quán)限才可以。
[0043] 為了能夠更好的說明本發(fā)明的設(shè)計(jì)方式,現(xiàn)舉一個(gè)場景:
[0044] 在游戲數(shù)據(jù)分析產(chǎn)品中,Game對象用于描述游戲的相關(guān)屬性,如游戲類型,開發(fā) 商,終端平臺(tái)等,其中有一個(gè)特殊的屬性,表示當(dāng)前登錄用戶能否看到該游戲的數(shù)據(jù),但是 用戶的權(quán)限數(shù)據(jù)統(tǒng)一被用戶中心的系統(tǒng)所管理,因此該屬性需要通過遠(yuǎn)程調(diào)用的方式從用 戶中心獲取。用代碼簡要描述如下
[0047] 假設(shè)現(xiàn)在有界面展示需求,需要用列表顯示所有的游戲,但是需要按照當(dāng)前用戶 有無權(quán)限進(jìn)行排序,畢竟將無權(quán)限的游戲放在列表最上面但是又無法操作,會(huì)是非常糟糕 的產(chǎn)品用戶體驗(yàn)設(shè)計(jì)。為了實(shí)現(xiàn)此需求,一般是使用JDK自帶的排序工具進(jìn)行排序,如
[0048] fh
[0049] 但是上面的實(shí)現(xiàn)雖然易于理解,但是卻存在非常大的性能問題,因?yàn)樵谂判虻倪^ 程中,不管采用哪種排序算法,因?yàn)闀?huì)存在多次的兩兩比較,所以同一個(gè)Game實(shí)例會(huì)被調(diào) 用多次getAccessPermission函數(shù),通過查看getAccessPermission函數(shù)實(shí)現(xiàn),能夠得到同 樣每個(gè)Game