江健鋒 徐振平



摘要:Springboot是在Spring基礎(chǔ)上衍生的實(shí)用性框架,其目的并不是要替代Spring,而是為了改變Spring框架中煩瑣的配置項(xiàng)而誕生。其特點(diǎn)是更好地和第三方庫(kù)結(jié)合進(jìn)行開(kāi)發(fā),減少大量的配置代碼,達(dá)到開(kāi)箱即用的目的。而Springboot的最小系統(tǒng)架構(gòu),是在web開(kāi)發(fā)環(huán)境中,把安全驗(yàn)證、數(shù)據(jù)交互、錯(cuò)誤返回等web程序基本要素結(jié)合成一個(gè)架構(gòu)系統(tǒng),不隨業(yè)務(wù)內(nèi)容改變。而當(dāng)項(xiàng)目業(yè)務(wù)內(nèi)容發(fā)生改變時(shí),只需要在該最小系統(tǒng)的基礎(chǔ)上,實(shí)現(xiàn)業(yè)務(wù)邏輯即可。
關(guān)鍵詞:Java;Springboot;Mybatis;SpringSecurity;Json
中圖分類(lèi)號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2021)04-0062-02
1引言
作為Apache基金的頂級(jí)項(xiàng)目,Springboot框架的提出是為了解決傳統(tǒng)Spring框架配置煩瑣的問(wèn)題,而且配備了一系列諸如SQL、NoSQL數(shù)據(jù)庫(kù)、分布式系統(tǒng)等開(kāi)源項(xiàng)目作為擴(kuò)展項(xiàng),堪稱全家桶,是現(xiàn)在絕大多數(shù)互聯(lián)網(wǎng)單系統(tǒng)或分布式系統(tǒng)的必備框架。而傳統(tǒng)的基于Springboot框架的系統(tǒng)只是對(duì)Spring全家桶按需使用,沒(méi)有明確規(guī)劃,在后期會(huì)造成項(xiàng)目的結(jié)構(gòu)混亂,例如:返回?cái)?shù)據(jù)不統(tǒng)一造成前后端聯(lián)調(diào)復(fù)雜;缺乏全局錯(cuò)誤處理,錯(cuò)誤日志復(fù)雜,定位問(wèn)題變得困難。所以,為了排除不同項(xiàng)目業(yè)務(wù)對(duì)系統(tǒng)造成的差異性,我們可以構(gòu)建最小系統(tǒng)框架,方便項(xiàng)目的拓建,并且給團(tuán)隊(duì)一個(gè)適應(yīng)的編程規(guī)范。
2系統(tǒng)架構(gòu)描述
2.1最小系統(tǒng)架構(gòu)
如圖1,絕大多數(shù)系統(tǒng)架構(gòu)核心必須包含三大模塊,與用戶相關(guān)的業(yè)務(wù)模塊;連接底層的數(shù)據(jù)管理模塊;以及用于中間協(xié)調(diào)系統(tǒng)的基礎(chǔ)功能模塊;就企業(yè)級(jí)而非個(gè)人的項(xiàng)目來(lái)說(shuō),除了業(yè)務(wù)模塊不一樣之外,基礎(chǔ)模塊在邏輯功能上是共通的。最小系統(tǒng)架構(gòu),其實(shí)就是構(gòu)建系統(tǒng)的安全功能,數(shù)據(jù)交互封裝,全局異常處理,數(shù)據(jù)庫(kù)連接等模塊功能,同時(shí)避免受業(yè)務(wù)邏輯的干擾,成為脫離業(yè)務(wù)單獨(dú)運(yùn)行的系統(tǒng)。下文將對(duì)系統(tǒng)的三個(gè)模塊進(jìn)行剖析。
2.2系統(tǒng)采用技術(shù)
2.2.1基礎(chǔ)功能模塊
如圖2所示,對(duì)于基礎(chǔ)功能模塊來(lái)說(shuō),有三個(gè)功能是不可或缺的,分別是安全驗(yàn)證,前后端數(shù)據(jù)交互,異常處理,下文將對(duì)這個(gè)功能逐一說(shuō)明。
1)全局異常處理
眾所周知,用戶的輸入不可能完全按照程序員的意愿來(lái)進(jìn)行;同時(shí),程序員無(wú)法對(duì)程序運(yùn)行的各種情況考慮的面面俱到,因此,運(yùn)行時(shí)出現(xiàn)異常或者錯(cuò)誤是很難避免的。如果把程序內(nèi)部響應(yīng)的錯(cuò)誤直接返回給用戶,會(huì)給用戶造成疑惑。綜上,我們應(yīng)該對(duì)程序所有可能發(fā)生的錯(cuò)誤都進(jìn)行捕捉,把錯(cuò)誤信息封裝,挑選用戶能理解的部分進(jìn)行返回,提高用戶體驗(yàn)度,全局異常處理就顯得十分重要。
全局異常處理應(yīng)用的是SpringMVC提供的組件增強(qiáng)注解@ControllerAdvice,以及捕捉系統(tǒng)異常的注解@ExceptionHandler來(lái)進(jìn)行全局聲明,對(duì)于不同的類(lèi)型,可以返回不同的消息。對(duì)應(yīng)部分代碼如下:
@ControllerAdvice
@Slf4j
publicclassGlobalExceptionHandler {
// 捕獲運(yùn)行時(shí)異常
@ExceptionHandler(RuntimeException.class)
@ResponseBody
publicJsonResulthandlerBusinessException(RuntimeException ex) {
log.error("錯(cuò)誤: {}"ex.getErrMsg());
ex.printStackTrace();
returnJsonResult.failure(ex);
}
}
2)前后端數(shù)據(jù)封裝
JSON(JavaScript Object Notation)是一種廣泛應(yīng)用的數(shù)據(jù)交換格式,其簡(jiǎn)潔而又清晰的層次結(jié)構(gòu)讓其逐漸取代XML稱為前后端格式交互的主要格式[1]。在Springboot的核心jar包spring-boot-starter-web中,默認(rèn)封裝了JSON工具包,當(dāng)前端對(duì)后臺(tái)進(jìn)行請(qǐng)求的時(shí)候,可以設(shè)置返回的文本格式為JSON。但是JSON簡(jiǎn)單清晰的特點(diǎn)只體現(xiàn)在數(shù)據(jù)傳輸方面,Springboot框架并沒(méi)有對(duì)返回的數(shù)據(jù)內(nèi)容格式上做任何要求,即返回的JSON中,可以是一串文字,也可以是某種層次結(jié)構(gòu)。
根據(jù)計(jì)算機(jī)網(wǎng)絡(luò)傳輸?shù)闹R(shí),我們知道,當(dāng)系統(tǒng)正常運(yùn)轉(zhuǎn)并返回時(shí),計(jì)算機(jī)狀態(tài)碼為200;服務(wù)器內(nèi)部執(zhí)行錯(cuò)誤狀態(tài)碼會(huì)返回5xx來(lái)代表不同的錯(cuò)誤狀態(tài)。我們可以結(jié)合全局異常處理的內(nèi)容,不管用戶傳輸給我們的數(shù)據(jù)是什么,只要程序能夠接收,http攜帶的狀態(tài)碼都返回200,我們可以把程序的錯(cuò)誤或者程序員自定義的錯(cuò)誤內(nèi)容封裝到JSON中,所以我們必須有一個(gè)代表狀態(tài)碼的code字段和中文解析message字段。除了錯(cuò)誤返回之外,程序必須能夠正常執(zhí)行并返回?cái)?shù)據(jù),返回?cái)?shù)據(jù)的數(shù)據(jù)是一個(gè)對(duì)象,我們用data字段來(lái)表示。最終,前后端通用的JSON文本格式為。
{
code:狀態(tài)碼(數(shù)字),
msg:中文解析(字符串),
data:程序返回的數(shù)據(jù)(對(duì)象)
}
3)安全模塊
本文使用的安全模塊采用的是SpringSecurity框架,SpringSecurity是一款企業(yè)級(jí)的權(quán)限認(rèn)證授權(quán)框架,作為Spring全家桶的一員,和Springboot具有很好的契合性。同時(shí),安全模型的結(jié)構(gòu)設(shè)計(jì)采用RBAC(Role-Based Access Control 基于角色的訪問(wèn)控制)模型設(shè)計(jì)。文獻(xiàn)2通過(guò)提出一致性準(zhǔn)則、安全性準(zhǔn)則和可用性準(zhǔn)則分別證明了RBAC模型安全特性與該三項(xiàng)準(zhǔn)則安全特性相一致,證明了RBAC的可靠性[2]。
2.2.2 數(shù)據(jù)管理模塊
項(xiàng)目必須考慮后期的擴(kuò)展性,而隨著業(yè)務(wù)數(shù)據(jù)量的激增,框架對(duì)數(shù)據(jù)的承受能力必須有很好的把握,或者說(shuō)要有足夠的擴(kuò)展性,在后期進(jìn)行擴(kuò)展。作為一個(gè)抽象的單系統(tǒng),最小系統(tǒng)架構(gòu)來(lái)說(shuō),最大化地減少系統(tǒng)負(fù)擔(dān)并且有足夠的擴(kuò)展性,都是不可或缺的。圖3是數(shù)據(jù)管理模塊的抽象結(jié)構(gòu)圖,其中不包含任何數(shù)據(jù)分析的模塊,只做數(shù)據(jù)管理功能。
1)ORM框架
如圖3所示,ORM(Object Relational Mapping,對(duì)象關(guān)系映射)框架,用于實(shí)現(xiàn)面向?qū)ο笳Z(yǔ)言里不同類(lèi)型系統(tǒng)的數(shù)據(jù)之間的轉(zhuǎn)換[3]。在Java語(yǔ)言中,JDK(Java development kit Java開(kāi)發(fā)工具包)提供了數(shù)據(jù)庫(kù)映射數(shù)據(jù)的API,作為數(shù)據(jù)返還,ORM作為框架接收;底層需要數(shù)據(jù)庫(kù)驅(qū)動(dòng),為了提高數(shù)據(jù)庫(kù)復(fù)用率,提高系統(tǒng)吞吐率,我們可以使用數(shù)據(jù)庫(kù)連接池來(lái)進(jìn)行并發(fā)優(yōu)化。
基于Java語(yǔ)言的開(kāi)源ORM框架有Hibernate和Mybatis,前者是全自動(dòng)化的集成框架,包括數(shù)據(jù)映射,數(shù)據(jù)庫(kù)建表,增刪改查語(yǔ)言的自動(dòng)生成;而Mybatis則是一個(gè)半自動(dòng)框架,提供了大量接口供用戶調(diào)用,這種半自動(dòng)化給了用戶很大的自由性,所以最小系統(tǒng)框架選擇使用Mybatis框架。
2)數(shù)據(jù)庫(kù)連接池
著名的數(shù)據(jù)庫(kù)連接池開(kāi)源組件有Druid,c3p0,dbcp。本系統(tǒng)采用的數(shù)據(jù)庫(kù)連接池是阿里開(kāi)源的Druid,相比于其他兩款數(shù)據(jù)庫(kù)連接池,Druid提供了強(qiáng)大的擴(kuò)展和監(jiān)控功能,在適應(yīng)大數(shù)據(jù)方面,容錯(cuò)率和性能上都相當(dāng)?shù)某錾?/p>
3總結(jié)
本文從框架的層面,分析和綜合了絕大多數(shù)程序架構(gòu)的特點(diǎn)和共性,抽象化地提出了互聯(lián)網(wǎng)應(yīng)用最小系統(tǒng)架構(gòu)的概念。其特點(diǎn)是抽離了業(yè)務(wù)邏輯實(shí)現(xiàn)系統(tǒng)運(yùn)行的最小化,同時(shí)保證了系統(tǒng)的可擴(kuò)展性。
參考文獻(xiàn):
[1] 百度.JSON[EB/OL].[2020-05-24].https://baike.baidu.com/item/JSON,2015-5-11.
[2] 熊厚仁,陳性元,張斌,等.基于RBAC的授權(quán)管理安全準(zhǔn)則分析與研究[J].計(jì)算機(jī)科學(xué),2015,42(3):117-123.
[3] 百度.ORM 對(duì)象關(guān)系映射[EB/OL]. [2020-05-24].https://baike.baidu.com/item對(duì)象關(guān)系映射/311152?fromtitle=ORM&fromid=3583252&fr=aladdin.
【通聯(lián)編輯:代影】