spring aop通過注解實現日志記錄


首先是幾個概念:連接點(Joinpoint)、切點(Pointcut)、增強(Advice)、切面(Aspect)

另外也要使用到注解。

需求:通過注解定義LogEnable。然后程序運行能夠識別定義了LogEnable注解的方法記錄日志。

1.定義注解 

package cn.duanjt.util;

import java.lang.annotation.*;

/**
 * 記錄日志的注解類
 * @author 段江濤
 * @date 2018-11-08
 */
@Target(ElementType.METHOD)//表示用於標識方法
@Retention(RetentionPolicy.RUNTIME)//表示運行時保留
public @interface LogEnable {
    /**
     * 主要是標志日志的描述信息
     * @return
     */
    String note() default "";
}

 

2.定義需要監聽的類和方法

package cn.duanjt.service;

import org.springframework.stereotype.Service;

import cn.duanjt.Pojo.Student;
import cn.duanjt.util.LogEnable;

@Service
public class StudentService {
    //定義注解,然后描述當前方法的作用
    @LogEnable(note="獲取學生信息")
    public Student getStudent(int id) {
        if (id == 0) {
            throw new RuntimeException("編碼不能為0");
        }
        Student stu = new Student();
        stu.setId(id);
        stu.setName("zhangsan");
        stu.setAddr("重慶");
        return stu;
    }

    //未定義注解,將不會被監聽
    public int getId(int id) {
        return id + 1;
    }
}

 

3.定義切面,記錄日志

package cn.duanjt.util;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogHelper {
    // 沒有單獨定義切點,直接在環繞方法里面處理[包cn.duanjt.service下面的所有類下面的所有方法,同時包含LogEnable注解的將被監聽]
    @Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)")
    public Object around(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        long time = System.currentTimeMillis();                        //記錄開始時間
        String className = point.getTarget().getClass().getName();    // 類名
        String method = className + "." + signature.getName();        //方法名
        Object[] args = point.getArgs();                            // 參數
        
        LogEnable logEnable= signature.getMethod().getAnnotation(LogEnable.class);
        String logNote=logEnable.note();                            //日志信息
        try {
            Object result = point.proceed();
            System.out.println("方法名:" + method);
            System.out.println("參數:" + StringUtils.join(args));
            System.out.println("返回值:" + result.toString());
            System.out.println("日志功能:" + logNote);
            System.out.println("耗時:" + (System.currentTimeMillis() - time) + "毫秒");
            System.out.println("-----------------------");
            return result;
        } catch (Exception e) {
            System.out.println("方法名1:" + method);
            System.out.println("參數:" + StringUtils.join(args));
            System.out.println("日志功能:" + logNote);
            System.out.println("異常信息:" + e.getMessage());
            System.out.println("耗時:" + (System.currentTimeMillis() - time) + "毫秒");
            System.out.println("-----------------------");
            return null;
        } catch (Throwable e) {
            return null;
        }

    }
}

 

4.在主程序上要加上注解@EnableAspectJAutoProxy。我這里使用的是springboot,如下:

package cn.duanjt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@ComponentScan("cn.duanjt")
@EnableAspectJAutoProxy //表示啟用AOP
public class ServerDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerDemoApplication.class, args);
    }
}

 

 

最后,運行結果如下:

方法名:cn.duanjt.service.StudentService.getStudent
參數:1
返回值:Student [id=1, name=zhangsan, addr=重慶]
日志功能:獲取學生信息
耗時:0毫秒
-----------------------

 

 

注意:

1. @EnableAspectJAutoProxy用於開啟全局的AOP

2. LogHelper類上面的@Aspect和@Component是必須的,前者用於標注是切面,后者用於將對象注入到spring容器

3. 切面表達式@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)").一定需要execution。詳細的可以下去再了解

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM