java_切面日志


切面日志舉例

package com.keyba1;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *
 * @author KeyBa
 * @date 2019/6/13
 * 記錄日志
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}
package com.keyba1;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 *
 * @author KeyBa
 * @date 2019/6/13
 * 注釋式日志切面
 */
@Aspect
@Slf4j
@Component
public class LogAspect {

    @Pointcut("@annotation(Log)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 執行方法
        Object result = joinPoint.proceed();
        // 執行時長(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //異步保存日志
        saveLog(joinPoint, time);
        return result;
    }

    void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = signature.getName();
        // 請求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        log.info("------------------------接口日志-----------------------" + "\n" + "類名稱:" + className
                + "\n" + "方法名:" + methodName + "\n" + "執行時間:" + time + "毫秒");
        log.info("接口參數"+"\n"+ Arrays.toString(joinPoint.getArgs()));
    }
}
package com.keyba1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Keyba
 */
@RestController
@SpringBootApplication
public class LogUseApplication {
    @RequestMapping("/")
    @Log
    String myApp(String strParam1,  String intParam2) {
        System.out.println("hello");
        System.out.println("strParam1: " + strParam1);
        System.out.println("intParam2: " + intParam2);
        return "Hello";
    }

    public static void main(String[] args) {
        SpringApplication.run(LogUseApplication.class, args);
    }
}
package com.keyba2;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 *
 * @author KeyBa
 * @date 2019/6/13
 * 無注解式切面
 */
@Component  //聲明組件
@Aspect //  聲明切面
@ComponentScan  //組件自動掃描
@EnableAspectJAutoProxy //spring自動切換JDK動態代理和CGLIB
public class LogAspect2 {
    @Resource
    HttpServletRequest request;
    /**
     * 自定義日志
     */
    private Logger logger = LoggerFactory.getLogger(LogAspect2.class);

    /**
     * 在方法執行前進行切面
     */
//    @Pointcut("execution(* com.keyba1..*.*(..)) && (@annotation(org.springframework.web.bind.annotation.GetMapping)||@annotation(org.springframework.web.bind.annotation.PutMapping)||@annotation(org.springframework.web.bind.annotation.DeleteMapping)||@annotation(org.springframework.web.bind.annotation.PostMapping)||@annotation(org.springframework.web.bind.annotation.RequestMapping))")
    public void log() {
    }

    //@Before("log()")
    public void before(JoinPoint point) {
        logger.info("---------------------請求開始---------------------");
        logger.info("請求地址:" + request.getRequestURL().toString());
        logger.info("請求方式:" + request.getMethod());
        logger.info("請求類方法:" + point.getSignature());
        logger.info("請求類方法參數:" + Arrays.toString(point.getArgs()));
        logger.info("-------------------------------------------------");
    }
}
package com.keyba3;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import com.keyba1.Log;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by KeyBa on 2019/6/13.
 * 使用org.projectlombok的@slf4j代替private final Logger logger = LoggerFactory.getLogger(XXX.class);
 * 使用log方法需要安裝lombox插件,使用@Data注解可以為一個bean自動生成getter , setter方法及toString 方法
 */
@Aspect
@Component
@Slf4j
public class TestAspect {

    //com.kzj.kzj_rabbitmq.controller 包中所有的類的所有方法切面
    //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.*.*(..))")

    //只針對 MessageController 類切面
    //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.MessageController.*(..))")

    //統一切點,對com.keyba及其子包中所有的類的所有方法切面
    //@Pointcut("execution(public * com.keyba1..*.*(..))")
    @Pointcut("@annotation(Log)")
    public void Pointcut() {
    }

    //前置通知
    @Before("Pointcut()")
    public void beforeMethod(JoinPoint joinPoint) {
        log.info("調用了前置通知");
    }

    //@After: 后置通知
    @After("Pointcut()")
    public void afterMethod(JoinPoint joinPoint) {
        log.info("調用了后置通知");
    }

    //@AfterRunning: 返回通知 rsult為返回內容
    @AfterReturning(value = "Pointcut()", returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, Object result) {
        log.info("調用了返回通知");
    }

    //@AfterThrowing: 異常通知
    @AfterThrowing(value = "Pointcut()", throwing = "e")
    public void afterReturningMethod(JoinPoint joinPoint, Exception e) {
        log.info("調用了異常通知");
    }

    //@Around:環繞通知1
    //@Around("Pointcut()")
    //public Object Around(ProceedingJoinPoint pjp) throws Throwable {
    //    log.info("around執行方法之前");
    //    Object object = pjp.proceed();
    //    log.info("around執行方法之后--返回值:" + object);
    //    return object;
    //}

    //@Around:環繞通知2
    @Around("Pointcut()")
    public Object Around(ProceedingJoinPoint pjp) throws Throwable {
        Map<String, Object> data = new HashMap<>();
        //獲取目標類名稱
        String clazzName = pjp.getTarget().getClass().getName();
        //獲取目標類方法名稱
        String methodName = pjp.getSignature().getName();

        //記錄類名稱
        data.put("clazzName", clazzName);
        //記錄對應方法名稱
        data.put("methodName", methodName);
        //記錄請求參數
        data.put("params", pjp.getArgs());
        //開始調用時間
        // 計時並調用目標函數
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        Long time = System.currentTimeMillis() - start;

        //記錄返回參數
        data.put("result", result);

        //設置消耗總時間
        data.put("consumeTime", time);
        System.out.println(data);
        return result;
    }
}


免責聲明!

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



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