切面日志举例

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;
    }
}
posted on 2019-08-17 00:24  liehen2046  阅读(1477)  评论(0编辑  收藏  举报