使用Spring Aop自定義註解實現自動記錄日誌

百度加本身琢磨,如下親測有效,因此寫下來記錄,也方便本身回顧瀏覽加深印象之類,有什麼問題能夠評論一塊兒解決,不完整之處也請大佬指正,一塊兒進步哈哈
(1)首先配置文件:java

<!-- 聲明自動爲spring容器中配置@aspectj切面的bean建立代理 ,織入切面 -->
    <aop:aspectj-autoproxy />
    <!-- 開啓註解掃描 -->
    <context:component-scan base-package="com.ky.zhjd.**"/>
    <!-- 爲true說明代理基於類被建立(默認false,基於接口被建立) -->
    <aop:config proxy-target-class="true"></aop:config>

(2)建立一個自定義註解類spring

注意建立時選Annotation,類名我叫ArchivesLog(日誌檔案的意思)。數據庫

ArchivesLog.java內容:json

package com.ky.zhjd.common.log;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 
 * 自定義註解類
 * @author ddz
 *
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface ArchivesLog {

    /** 要執行的操做類型好比:添加操做 **/  
    public String operationType() default "";  

    /** 要執行的操做名稱好比:添加一條用戶數據 **/  
    public String operationName() default ""; 
    
}

(3)新建一個切面類,我叫LogAspect.javaapp

package com.ky.zhjd.common.log;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 切面類
 * 
 * @author ddz
 *
 */
@Aspect
@Component("logAspect")
public class LogAspect {

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

    // 配置織入點
    @Pointcut("@annotation(ArchivesLog)")
    public void logPointCut() {
    }

    /**
     * 前置通知 用於攔截操做,在方法返回後執行
     * 
     * @param joinPoint 切點
     */
    @AfterReturning(pointcut = "logPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        handleLog(joinPoint, null);
    }

    /**
     * 攔截異常操做,有異常時執行
     * 
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfter(JoinPoint joinPoint, Exception e) {
        handleLog(joinPoint, e);
    }

    private void handleLog(JoinPoint joinPoint, Exception e) {
        try {
            // 得到註解
            ArchivesLog controllerLog = getAnnotationLog(joinPoint);
            System.out.println("---------------自定義註解:" + controllerLog);
            if (controllerLog == null) {
                return;
            }
            // 得到方法名稱
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            String type = controllerLog.operationType();
            String name = controllerLog.operationName();
            // 打印日誌  這裏能夠進行插入數據庫操做
            log.info(">>>>>>>>>>>>>操做類型:", type);
            log.info(">>>>>>>>>>>>>操做名稱:", name);
            log.info(">>>>>>>>>>>>>類名:", className);
            log.info(">>>>>>>>>>>>>方法名:", methodName);
        } catch (Exception exp) {
            // 記錄本地異常日誌
            log.error("==前置通知異常==");
            log.error("異常信息:", exp.getMessage());
            exp.printStackTrace();
        }
    }

    /**
     * 是否存在註解,若是存在就獲取
     */
    private static ArchivesLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            // 拿到自定義註解中的信息
            return method.getAnnotation(ArchivesLog.class);
        }
        return null;
    }
}

(4)在方法上使用註解 , 而後調用該方法學習

@ArchivesLog(operationType="查詢操做",operationName="查詢一條用戶詳情")
    @RequestMapping(value = "/findByid", produces={"application/json;charset=UTF-8"})
    public @ResponseBody BaseResult<Object> findByid(String id) {
        String s="11";
        BaseResult<Object> r=userService.findById(s);
        System.out.println(r+">>>>>>>>>>");
    return r;
    
    }

ok 上效果:spa

 

 有什麼不完善的地方歡迎指出,一塊兒學習3d

相關文章
相關標籤/搜索