springboot+aop切点记录请求和响应信息

2018-12-25  本文已影响0人  哦00

本篇主要分享的是springboot中结合aop方式来记录请求参数和响应的数据信息;这里主要讲解两种切入点方式,一种方法切入,一种注解切入;首先创建个springboot测试工程并通过maven添加如下依赖:

                    org.springframework.boot            spring-boot-starter-aop                                    com.alibaba            fastjson            1.2.44       

  先来说方法的切点方式,需要创建个名为LogAspect的组件类,然后用@Aspect注解修饰组件类,再通过设置方法切入点方式做公共日志记录,如下创建切入点:

//切点入口 Controller包下面所有类的所有方法privatefinal String pointcut ="execution(* com.platform.Controller..*(..))";

    //切点@Pointcut(value = pointcut)

    publicvoid log() {

    }

  这里的execution( com.platform.Controller..(..))主要的意思是:切入点入口是Controller包下面所有类的所有方法;再来通过@Around环绕注解方法里面做请求参数和响应信息的记录,如下代码:

@Around(value ="log()")

    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object result =null;

        StringBuilder sbLog =newStringBuilder("\n");

        try {

            sbLog.append(String.format("类名:%s\r\n", proceedingJoinPoint.getTarget().getClass().getName()));

            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();

            sbLog.append(String.format("方法:%s\r\n", methodSignature.getMethod().getName()));

            Object[] args = proceedingJoinPoint.getArgs();

            for (Object o : args) {

                sbLog.append(String.format("参数:%s\r\n", JSON.toJSON(o)));

            }

            longstartTime = System.currentTimeMillis();

            result = proceedingJoinPoint.proceed();

            longendTime = System.currentTimeMillis();

            sbLog.append(String.format("返回:%s\r\n", JSON.toJSON(result)));

            sbLog.append(String.format("耗时:%ss", endTime - startTime));

        } catch (Exception ex) {

            sbLog.append(String.format("异常:%s", ex.getMessage()));

        } finally {

            logger.info(sbLog.toString());

        }

        return result;

    }

  此刻主要代码就完成了,再来我们配置下日志的记录方式;首先在 resources目录增加名为logback-spring.xml的文件,其配置信息如:

1 2 6 7 8 9101112131415logback16171819WARN20-->2122%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n2324252627${logPathAll}2829${logPathAll}.%d{yyyy-MM-dd}.zip303132%date %level [%thread] %logger{36} [%file : %line] %msg%n33343536373839404142

  然后application.yml的配置信息如:

1logging:2config: classpath:logback-spring.xml3  logback:4    level: info #info ,debug5path: /home/app/data/applogs/weblog6appname: web

  此刻日志和公共的aop记录类都完成了,我们需要创建个测试用例,其代码如:

1@PostMapping("/addUser")2publicResponseEntity addUser(@RequestBody MoStudent moStudent) throws Exception {3        moStudent.setNumber(UUID.randomUUID().toString());4//        throw new Exception("错误了");5returnnewResponseEntity<>(moStudent, HttpStatus.OK);6}

  最后,通过postman模拟post请求,能够得到如下的日志结果:

  上面的方式切入点是所有方法,所有方法都记录日志可能有是不是需求想要的,此时可以通过注解的方式来标记想记录日志的方法;先来创建个日志注解:

1@Target(ElementType.METHOD) 2@Retention(RetentionPolicy.RUNTIME) 3@Documented 4public @interface LogAnnotation { 5/** 6    * 描述 7    * 8    * @return 9*/10String des()default"";11}

  同样再来创建注解的切入点:

1//匹配方法上包含此注解的方法2privatefinal String annotationPointCut ="@annotation(com.platform.Aop.LogAnnotation)";34//注解切点5@Pointcut(value = annotationPointCut)6publicvoid logAnnotation() {7}

  再通过@Around注解绑定具体的操作方法:

1@Around(value ="logAnnotation()") 2public Object aroundAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 3Object result =null; 4StringBuilder sbLog =newStringBuilder("\n"); 5try { 6sbLog.append(String.format("类名:%s\r\n", proceedingJoinPoint.getTarget().getClass().getName())); 7 8MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature(); 9Method method = methodSignature.getMethod();10LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);11if(logAnnotation !=null&& !logAnnotation.des().isEmpty()) {12sbLog.append(String.format("说明:%s\r\n", logAnnotation.des()));13            }14sbLog.append(String.format("方法:%s\r\n", method.getName()));1516Object[] args = proceedingJoinPoint.getArgs();17for (Object o : args) {18sbLog.append(String.format("参数:%s\r\n", JSON.toJSON(o)));19            }2021longstartTime = System.currentTimeMillis();22result = proceedingJoinPoint.proceed();23longendTime = System.currentTimeMillis();24sbLog.append(String.format("返回:%s\r\n", JSON.toJSON(result)));25sbLog.append(String.format("耗时:%ss", endTime - startTime));26}catch (Exception ex) {27sbLog.append(String.format("异常:%s", ex.getMessage()));28}finally {29            logger.info(sbLog.toString());30        }31return result;32}

  这个方法里需要注意的是注解方式相比第一种其实就多了如下几行代码:

1Method method = methodSignature.getMethod();2LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);3if(logAnnotation !=null&& !logAnnotation.des().isEmpty()) {4sbLog.append(String.format("说明:%s\r\n", logAnnotation.des()));5}

  下面是注解测试用例:

1@LogAnnotation(des ="注解记录日志")2@PostMapping("/addUser01")3publicResponseEntity addUser01(@RequestBody MoStudent moStudent) throws Exception {4        moStudent.setNumber(UUID.randomUUID().toString());5returnnewResponseEntity<>(moStudent, HttpStatus.OK);6}

欢迎工作一到五年的Java工程师朋友们加入Java群: 891219277 群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
上一篇下一篇

猜你喜欢

热点阅读