1. 程式人生 > 實用技巧 >【java】基於註解的日誌處理

【java】基於註解的日誌處理

基於註解和AOP實現的自定義日誌系統。只需要兩個類就能實現:

1. 註解類:設定自定義屬性屬性

2. 切面類:用於橫切註解,獲取註解屬性值,儲存日誌

方法一

註解類:

//註解類 
//屬性可以根據需要自行新增

@Target({ElementType.TYPE, ElementType.METHOD})//目標是方法
@Retention(RetentionPolicy.RUNTIME)//註解會在class中存在,執行時可通過反射獲取
//@Inherited
@Documented
public @interface SysLog {

    /**
     * 描述
     */
    String description() 
default ""; /** * 行為型別 * 1.違規行為;2.異常行為;3 一般行為 */ String behaviourType() default "3"; /** * 日誌風險級別 * 1緊急、2重要、3一般、4資訊 */ String level() default "4"; }

切面類:

@Aspect//宣告這是一個事務切面
@Slf4j
@Component//讓其被spring管理
public class SysLogAspect {

    @Around("@annotation(sysLog)")
    @SneakyThrows
    
public void around(ProceedingJoinPoint point, SysLog sysLog) { //-----------環繞通知開始----------- //儲存日誌的邏輯 Object obj = point.proceed(); //-----------環繞通知結束----------- //根據obj結果更新日誌邏輯 } }

測試類:

//測試類
@SysLog(description = "這是一個測試",behaviourType = "1",level = "2")
@PostMapping(
"/test") public String getTest(){ //業務邏輯 //... return "test"; }

方法二

其餘一致,切面類做了修改:

@Aspect//宣告這是一個事務切面
@Slf4j
@Component//讓其被spring管理
public class SysLogAspect {
    
    //宣告切點
    @Pointcut("@annotation(com.xx.xx.SysLog)")
    public void logPointCut(){}

    //執行的先後順序是 環繞通知開始-->前置通知before-->後置通知after-->環繞通知結束
    
    @Around("logPointCut()")
    @SneakyThrows
    public void around(ProceedingJoinPoint point, SysLog sysLog) {
        //-----------環繞通知開始-----------
        //ProceedingJoinPoint只能用於環繞通知,此引數寫在前置和後置通知中會報錯
        
        //獲取request、response
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestCOntextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        
        //儲存日誌的邏輯
        
        //相當於自己寫在controller中的程式碼
        Object obj = point.proceed();
        
        //-----------環繞通知結束-----------
        
        //根據obj結果更新日誌邏輯
        
    }
    
    //此外還可以加上前置通知 後置通知等
    @Before("logPointCut()")
    public void doBefore(JoinPoint point){
        //可通過point獲取方法名和類名
        String className = point.getTarget().getClass().getName();
        String methodName = point.getSignature().getName();
    }
    
    @After("logPointCut()")
    public void doAfter(JoinPoint point){
        
    }
}

持續更新!!!