SpringBoot 使用AOP統(tǒng)一處理web請求日志

通過AOP統(tǒng)一處理web請求日志,只需要添加兩個依賴即可:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

一般不需要其他任何配置,即可使用。

1.先定義一個注解,用來描述每個方法的用途等。

@Target(ElementType.METHOD) //表示該注解標(biāo)注在方法上
@Retention(RetentionPolicy.RUNTIME) //表示該注解保留到runtime階段,將被JVM保留,所以它能在運行時被JVM或其他使用反射機制的代碼所讀取和使用.
@Documented //表示該注解會被 javadoc 之類的工具處理, 所以注解類型信息也會被包括在生成的文檔中
public @interface LoggerManage {

    public String description();
}

2.先寫一個簡單的請求

@RestController
public class IndexController {

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    @LoggerManage(description = "獲取用戶名")
    public String getUserName(String userID, Integer age) {
        return "ArcherLj";
    }
}

3.實現(xiàn)web層日志切面

使用@Aspect注解將一個java類定義為切面類
使用@Pointcut定義一個切入點,可以是一個規(guī)則表達(dá)式,比如下例中某個package下的所有函數(shù),也可以是一個注解等。
使用@Before在切入點開始處切入內(nèi)容
使用@After在切入點結(jié)尾處切入內(nèi)容
使用@AfterReturning在切入點return內(nèi)容之后切入內(nèi)容(可以用來對處理返回值做一些加工處理)
使用@Around在切入點前后切入內(nèi)容,并自己控制何時執(zhí)行切入點自身的內(nèi)容
使用@AfterThrowing用來處理當(dāng)切入內(nèi)容部分拋出異常之后的處理邏輯

使用ThreadLocal對象來記錄請求處理的時間(直接在使用基本類型會有同步問題,所以我們可以引入ThreadLocal對象)

package com.example.demo;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


/**
 * Created by archerlj on 2017/6/23.
 */
@Aspect
@Component
public class LoggerAdvice {

    private Logger logger = Logger.getLogger(this.getClass());
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Before("within(com.example.demo.*) && @annotation(loggerManage)")
    public void addBeforeLogger(JoinPoint joinPoint, LoggerManage loggerManage) {
        logger.info("執(zhí)行--" + loggerManage.description() + "--開始");
        startTime.set(System.currentTimeMillis());
        logger.info(joinPoint.getSignature().toString());
        logger.info(parseParames(joinPoint.getArgs()));
    }

    @AfterReturning("within(com.example.demo.*) && @annotation(loggerManage)")
    public void addAfterReturningLogger(JoinPoint joinPoint, LoggerManage loggerManage) {
        logger.info("執(zhí)行--" + loggerManage.description() + "--結(jié)束");
        logger.info("執(zhí)行時間--" + (System.currentTimeMillis() - startTime.get()));
    }

    @AfterThrowing(pointcut = "within(com.example.demo.*) && @annotation(loggerManage)", throwing = "ex")
    public void addAfterThrowingLogger(JoinPoint joinPoint, LoggerManage loggerManage, Exception ex) {
        logger.error("執(zhí)行--" + loggerManage.description() + "--異常", ex);
    }

    private String parseParames(Object[] parames) {
        if (null == parames || parames.length <= 0) {
            return "";
        }
        StringBuffer param = new StringBuffer("參數(shù)--");
        for (Object obj : parames) {
            String va = ToStringBuilder.reflectionToString(obj);
            param.append(va).append("  ");
        }
        return param.toString();
    }
}

Spring AOP支持在切入點表達(dá)式中使用如下的切入點指示符:

execution - 匹配方法執(zhí)行的連接點,這是你將會用到的Spring的最主要的切入點指示符。

within - 限定匹配特定類型的連接點(在使用Spring AOP的時候,在匹配的類型中定義的方法的執(zhí)行)。

this - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中bean reference(Spring AOP 代理)是指定類型的實例。

target - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中目標(biāo)對象(被代理的應(yīng)用對象)是指定類型的實例。

args - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中參數(shù)是指定類型的實例。

@target - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中正執(zhí)行對象的類持有指定類型的注解。

@args - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中實際傳入?yún)?shù)的運行時類型持有指定類型的注解。

@within - 限定匹配特定的連接點,其中連接點所在類型已指定注解(在使用Spring AOP的時候,所執(zhí)行的方法所在類型已指定注解)。

@annotation - 限定匹配特定的連接點(使用Spring AOP的時候方法的執(zhí)行),其中連接點的主題持有指定的注解。

4.設(shè)置log文件位置

application.properties:

logging.file=./demo.log
logging.level.com.example.demo=INFO
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=ERROR

訪問http://localhost:8080/index?userID=sadfieg3&age=129
結(jié)果如下

: 執(zhí)行--獲取用戶名--開始
: String com.example.demo.IndexController.getUserName(String,Integer)
: 參數(shù)--java.lang.String@250928e9[value={s,a,d,f,i,e,g,3},hash=1708579352]  java.lang.Integer@ded028e[value=129]  
: 執(zhí)行--獲取用戶名--結(jié)束
: 執(zhí)行時間--20

最后幫朋友打個小廣告

一個有趣的迷你小程序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,480評論 2 379

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,825評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,922評論 6 342
  • AOP實現(xiàn)可分為兩類(按AOP框架修改源代碼的時機): 靜態(tài)AOP實現(xiàn):AOP框架在編譯階段對程序進行修改,即實現(xiàn)...
    數(shù)獨題閱讀 2,330評論 0 22
  • Via http://jinnianshilongnian.iteye.com/blog/1415606 http...
    xiaobinZh閱讀 1,570評論 0 52
  • 曾經(jīng),每一個文青心里都有一個咖啡館之夢,每天睡到自然醒,在濃郁的咖啡香里看書聽歌曬太陽。 現(xiàn)在,每一個人心里都有一...
    白狗的碗閱讀 509評論 0 6