SpringAOP的應(yīng)用:統(tǒng)計(jì)接口執(zhí)行時(shí)間

什么是AOP

Spring是java面向?qū)ο缶幊痰闹髁骺蚣埽渲饕枷胗袃蓚€(gè):反轉(zhuǎn)控制(IOC)和面向切面(AOP)。

AOP(Aspect Oriented Programming)稱為面向切面編程,是對(duì)面向?qū)ο螅∣OP)的補(bǔ)充和完善袍祖。

普通的面向?qū)ο蠡诜庋b、繼承、多態(tài)等概念來(lái)建立一種對(duì)象層次結(jié)構(gòu)宾尚,但僅限于縱向?qū)哟危瑹o(wú)法做到橫向關(guān)聯(lián)。而日志煌贴、異常處理等功能涉及各個(gè)類御板,代碼橫向地散布在所有層次中,傳統(tǒng)OOP難以復(fù)用這些代碼牛郑。

而AOP利用一種稱為"橫切"的技術(shù)怠肋,剖解開(kāi)封裝的對(duì)象內(nèi)部,并將那些影響了多個(gè)類的公共行為封裝到一個(gè)可重用模塊淹朋,并將其命名為"Aspect"笙各,即切面。

所謂"切面"础芍,簡(jiǎn)單說(shuō)就是那些與業(yè)務(wù)無(wú)關(guān)杈抢,卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼仑性,降低模塊之間的耦合度惶楼,并有利于未來(lái)的可操作性和可維護(hù)性。

日志中統(tǒng)計(jì)執(zhí)行時(shí)間

對(duì)應(yīng)代碼中的關(guān)鍵方法虏缸,在日志中通過(guò)計(jì)時(shí)統(tǒng)計(jì)執(zhí)行時(shí)間鲫懒,可以監(jiān)控功能執(zhí)行是否正常,也可以觀察程序的性能刽辙,作為優(yōu)化效果的判斷依據(jù)窥岩。

統(tǒng)計(jì)執(zhí)行時(shí)間可以使用Stopwatch工具類,引入

import com.google.common.base.Stopwatch;

使用createStarted()開(kāi)始計(jì)時(shí)宰缤,結(jié)束時(shí)用elapsed統(tǒng)計(jì)耗時(shí)颂翼。

代碼示例如下:

import com.google.common.base.Stopwatch;

Stopwatch stopwatch = Stopwatch.createStarted();
/**
 * 功能代碼
 */
log.info("xxxxx,elapsed:{} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));

不過(guò)這種方式只能統(tǒng)計(jì)一個(gè)功能的耗時(shí),若現(xiàn)在有100個(gè)接口都需要統(tǒng)計(jì)耗時(shí)的話慨灭,顯然是沒(méi)辦法每個(gè)都去這么寫(xiě)的朦乏。

這時(shí)就需要配合AOP技術(shù)來(lái)實(shí)現(xiàn)了。

使用AOP構(gòu)建通用計(jì)時(shí)類

先放完整的實(shí)現(xiàn):

@Component
@Aspect
@Log4j
public class TimingUtil {
 
    @Pointcut("execution(* com.xxx.xx.controller..*.*(..))")
    private void pointCut(){}
 
    @Around("pointCut()")
    public Object timing(ProceedingJoinPoint joinPoint){
        Object object;
        Stopwatch stopwatch = Stopwatch.createStarted();
        try{
            object = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return null;
        }
        log.info("API request completed, takes " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms.");
        return object;
    }
}

來(lái)看這里面的關(guān)鍵點(diǎn):

1 Aspect和Component注解
Component注解對(duì)于Springboot來(lái)說(shuō)相當(dāng)于聲明bean并添加至xml配置中氧骤,加了Component的類編譯時(shí)就被視為Springboot項(xiàng)目的bean呻疹,進(jìn)行拼裝。

Aspect注解則聲明了該類是一個(gè)切面筹陵。

2 PointCut注解
該注解用來(lái)聲明AOP切面的切入點(diǎn)刽锤,或者說(shuō),告訴程序什么時(shí)候要使用切面介入朦佩。

execution表示在執(zhí)行某些方法時(shí)介入并思,是PointCut最常用的介入方式。

表達(dá)式格式為:(返回類型语稠,方法路徑.方法名(參數(shù)類型))

在本例中宋彼,要介入的是接口類以獲取時(shí)間,第一個(gè)* 代表不限制返回類型,接口類存放的路徑在com.xxx.xx.controller中输涕,后面..* 表示controller包下的所有類音婶。

再往后.*表示這個(gè)類下的所有方法,(..)代表不限制傳入的參數(shù)類型占贫。

3 Around注解
在捕獲切入點(diǎn)后桃熄,AOP類就可以進(jìn)行切面上的操作了先口。

根據(jù)需要處理的行為方式不同型奥,可以使用不同的注解標(biāo)記,例如前置處理@Before碉京、后置處理@AfterRunning厢汹、異常處理@AfterThrowing、環(huán)繞處理@Around等等谐宙。

這里我們要記錄接口執(zhí)行的時(shí)間烫葬,因此需要在接口調(diào)用前開(kāi)始計(jì)時(shí),在接口返回后停止計(jì)時(shí)凡蜻,所以需要環(huán)繞處理搭综。

需要在Around注解后標(biāo)記切入方法名,因?yàn)榭赡懿恢挂粋€(gè)切入划栓。

使用Around注解時(shí)兑巾,切面方法必須使用入?yún)roceedingJoinPoint,代表切入點(diǎn)忠荞,切面方法返回類型默認(rèn)選object(當(dāng)然蒋歌,如果可以確保所有返回類型一致,也可以直接定義)委煤。

joinPoint.proceed()這個(gè)方法表示執(zhí)行切入點(diǎn)的方法堂油,在此之前的代碼部分為前置處理,在此之后的代碼部分為后置處理碧绞。

所以在執(zhí)行proceed之前啟動(dòng)秒表府框,在執(zhí)行后記錄時(shí)間,這樣對(duì)所有接口進(jìn)行計(jì)時(shí)的功能就完成了讥邻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末迫靖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子计维,更是在濱河造成了極大的恐慌袜香,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲫惶,死亡現(xiàn)場(chǎng)離奇詭異蜈首,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門欢策,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吆寨,“玉大人,你說(shuō)我怎么就攤上這事踩寇∽那澹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵俺孙,是天一觀的道長(zhǎng)辣卒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)睛榄,這世上最難降的妖魔是什么荣茫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮场靴,結(jié)果婚禮上啡莉,老公的妹妹穿的比我還像新娘。我一直安慰自己旨剥,他們只是感情好咧欣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著轨帜,像睡著了一般魄咕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阵谚,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天蚕礼,我揣著相機(jī)與錄音,去河邊找鬼梢什。 笑死奠蹬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嗡午。 我是一名探鬼主播囤躁,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荔睹!你這毒婦竟也來(lái)了狸演?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤僻他,失蹤者是張志新(化名)和其女友劉穎宵距,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吨拗,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡满哪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年婿斥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哨鸭。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡民宿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出像鸡,到底是詐尸還是另有隱情活鹰,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布只估,位于F島的核電站志群,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仅乓。R本人自食惡果不足惜赖舟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一蓬戚、第九天 我趴在偏房一處隱蔽的房頂上張望夸楣。 院中可真熱鬧,春花似錦子漩、人聲如沸豫喧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)紧显。三九已至,卻和暖如春缕棵,著一層夾襖步出監(jiān)牢的瞬間孵班,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工招驴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篙程,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓别厘,卻偏偏與公主長(zhǎng)得像虱饿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子触趴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • IoC 容器 Bean 的作用域 自定義作用域?qū)崿F(xiàn) org.springframework.beans.facto...
    Hsinwong閱讀 2,471評(píng)論 0 7
  • 概述 Spring是什么氮发? Spring是一個(gè)開(kāi)源框架,為了解決企業(yè)應(yīng)用開(kāi)發(fā)的復(fù)雜性而創(chuàng)建的冗懦,但是現(xiàn)在已經(jīng)不止于企...
    瑯筑閱讀 1,166評(píng)論 2 8
  • Spring的AOPAOP的基本概念基于注解的“零配置”方式定義切面Bean定義Before增強(qiáng)處理定義After...
    漸丶忘閱讀 1,604評(píng)論 0 0
  • 因?yàn)楣ぷ餍枨笏幔约喝チ私庖幌耡op并做下的記錄,當(dāng)然大部分都是參考他人博客以及官方文檔披蕉。 目錄 [關(guān)于 AOP](...
    forip閱讀 2,274評(píng)論 1 20
  • 雷雁雄10月12日總結(jié):今天白天做標(biāo)書(shū)颈畸,晚上接待客戶前塔。
    雷雁雄閱讀 104評(píng)論 0 0