AOP统一处理请求日志

2018-11-09  本文已影响0人  零下的雨

AOP是一种编码规范,是一种思想,是面向切面编程的一种思想。
是指将通用逻辑从业务逻辑中分离出来统一处理,


image.png

如图中所讲 记录请求和记录回复两个模块就可以分离出来,统一处理,中间的部分就是各自的业务处理部分。

添加AOP第一步:
添加maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

第二步:
建立处理文件,建立Aspect文件夹,建立HttpAspect类

package com.imooc.aspect;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/*
统一处理请求类
 */

//使用AOP技术需要使用@Aspect注解
//@Component 把类注入到spring容器中(泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。)
@Aspect
@Component
public class HttpAspect {
    //使用Before注解,在执行log方法前先执行“execution(public * com.imooc.controller.GirlController.getgirlslist(..))”
    //执行com.imooc.controller.GirlController.getgirlslist(..)的getgirlslist()方法
    //getgirlslist(..)  括号中的..是指这个方法中不管什么参数都会拦截,其实什么都不加也可以
    //com.imooc.controller.GirlController.*(..) 把方法名换成* 星号是指该类中所有的方法都会被拦截
//    @Before("execution(public * com.imooc.controller.GirlController.getgirlslist(..))")

    @Before("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log(){
        System.out.println("执行方法前,使用Aop统一处理日志");
    }

    //在方法执行完后打印日志
    @After("execution(public * com.imooc.controller.GirlController.*(..))")
    public void doAfter(){
        System.out.println("执行方法后,使用Aop统一处理日志");
    }




}

使用@Pointcut注解简化代码:
@Pointcut 注解,切入点注解,从哪个类开始切入使用AOP统一处理技术,
@Before和@After注解中都写入("log()")示例代码如下:

    //为了使代码更简单,可以这样写,使用@Pointcut注解
//    @Before("execution(public * com.imooc.controller.GirlController.*(..))")
    @Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log(){
    }

    //@Before注解可以这样写,调用方法之前先调用log()方法
    @Before("log()")
    public void doBefore(){
        System.out.println("执行方法前,使用Aop统一处理日志");
    }

    //在方法执行完后打印日志
//    @After("execution(public * com.imooc.controller.GirlController.*(..))")
    @After("log()")
    public void doAfter(){
        System.out.println("执行方法后,使用Aop统一处理日志");
    }

使用Logger打印日志,统一日志打印风格,代码如下:

    //定义一个私有的常量,用来存储日志
    private final static Logger logger= LoggerFactory.getLogger(HttpAspect.class);
    @Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log(){
    }

    //@Before注解可以这样写,调用方法之前先调用log()方法
    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        logger.info("执行方法前,使用Aop统一处理日志");

        //获取url、method、ip、类、方法等信息并打印成日志
        ServletRequestAttributes attributes= (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=attributes.getRequest();

        //获取url
        logger.info("url={}",request.getRequestURI());
        //获取method
        logger.info("method={}",request.getMethod());
        //获取ip
        logger.info("ip={}",request.getRemoteAddr());
        //获取方法,需要用joinpoint方法,先获取类名,再获取方法名
        logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"."+
                joinPoint.getSignature().getName());
        //使用joinpoint方法获取参数名
        logger.info("args={}",joinPoint.getArgs());
    }

    //在方法执行完后打印日志
    @After("log()")
    public void doAfter(){
        logger.info("执行方法后,使用Aop统一处理日志");
    }

在postman中调接口,查看控制台日志结果:


image.png

如何获取返回的内容呢?
需要先在Girl类中重写toString方法,要不然返回类的对象为哈希码

    //重写toString()方法
    @Override
    public String toString() {
        return "Girl{" +
                "id=" + id +
                ", cupSize='" + cupSize + '\'' +
                ", age=" + age +
                '}';
    }

在httpAspct类中写:

    //获取接口返回的内容
    @AfterReturning(returning = "object",pointcut = "log()")
    public void doAfterReturining(Object object){
        logger.info("returning={}",object);
    }

在postman中调接口,查看控制台日志结果:


image.png
上一篇下一篇

猜你喜欢

热点阅读