SpringBoot 通過AOP代理簡單打印日誌

前言

剛加入新公司,一來項目組長就讓我帶3個實習生,也是鴨梨山大啊。今天在旁邊看他們寫代碼,感覺基礎的能力還是可以的,不過技術上面還是有不少欠缺的啊。
比如:項目組長讓他們把Service層,每個方法都要加上日誌打印,執行該方法之前的,執行之後的,還要打印方法參數值。看他們一直就那樣手動的log.debug(),我也是很無奈。。當時就說了用AOP去實現很簡單的,尤其是本來項目就是基於SpringBoot的,連配置都省了。結果都不會,因爲我電腦還沒審批下來,當時就沒給他們演示了。回來寫了Demo,等電腦下來,就讓他們學學看,苦逼的花大半天加log,在我這裏只需要分分鐘的事,嘿嘿。

環境

  • jdk1.8
  • springboot 1.5.1.RELEASE

配置

需要注意的是,Mavenpom.xml文件再原有的springboot配置之上還要加一個aop的,如下:

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

添加以上配置會自動導入spring-aop, aspectjrt, aspectjweaver這幾個jar包的

AOP

這裏只爲了簡單的演示一下如何完成打印日誌需求:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

@Aspect
@Configuration
public class LoggerAopConfig {

    private static final Logger log = LoggerFactory.getLogger(LoggerAopConfig.class);

    // 只關注方法名爲find前綴的
    @Pointcut("execution(* find* (..))")
    public void executeService() {}


    @Before("execution(* find*(..))")
    public void invokeBefore(JoinPoint point) {
        String realClassName = getRealClassName(point);
        log.debug("調用-----"+ realClassName + " 執行 " + getMethodName(point) + " 方法之前");
    }

    @After("execution(* find*(..))")
    public void invokeAfter(JoinPoint point) {
        String realClassName = getRealClassName(point);
        log.debug("調用-----"+ realClassName + " 執行 " + getMethodName(point) + " 方法之後");
    }


    /**
     * 獲取被代理對象的真實類全名
     * @param point 連接點對象
     * @return 類全名
     */
    private String getRealClassName(JoinPoint point) {
        return point.getTarget().getClass().getName();
    }

    /**
     * 獲取代理執行的方法名
     * @param point 連接點對象
     * @return 調用方法名
     */
    private String getMethodName(JoinPoint point) {
        return point.getSignature().getName();
    }
}

其中關於JoinPoint有以下幾個常用方法:

  • Object[] getArgs:返回目標方法的參數
  • Signature getSignature:返回目標方法的簽名
  • Object getTarget:返回被織入增強處理的目標對象
  • Object getThis:返回AOP框架爲目標對象生成的代理對象

    注意:當使用@Around處理時,我們需要將第一個參數定義爲ProceedingJoinPoint類型,該類是JoinPoint的子類。

總結

技術是需要靈活變通的,當一個類似的代碼重複3-5遍的時候就應該要想想,有什麼辦法可以減少重複代碼了。當基礎技術學的差不多的時候,編程思想就能看出技術水平的高低啦,要想着擺脫低級搬磚碼農的處境,思想很關鍵。還要學的有很多,堅持。

發佈了84 篇原創文章 · 獲贊 71 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章