学习springBoot(八,AOP处理请求日志)

前言:AOP:将通用逻辑从业务逻辑中分离出来

一、在pom.xml中添加AOP依赖

<!--添加aop依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

二、往常的做法是在启动类上添加注解,但是aop不需要

三、建立我们的处理文件,首先建一个aspect包,再在包下面建议我们的类,

然后在类上面我们添加@Aspect注解和@Component注解如下:

/**
 * 系统日志,处理切面类
 */
@Aspect
@Component
public class HttpAspect {
    
}

四、我们现在要做的是在做一些增删改查前要验证是否登录了,下面我们就在HttpAspect下面进行验证和拦截。

@Aspect
@Component
public class HttpAspect {

    @Before("execution(public * com.imooc.controller.GirlController.girlList(..))")
    public void log(){
        System.out.println(11111);

    }
}

这里我们先验证一下girlList方法,格式就如上面的代码一样,下面我们运行程序进行测试!

这里我们还是用postman进行接口测试,看一下控制台:

打印出来了我们之前在HttpAspect中打印的数字!

若想把GirlController中的所有方法都添加此拦截,只需按照如下操作即可:

 @Before("execution(public * com.imooc.controller.GirlController.*(..))")

其中*号代表扫描所有的方法。

下面我们再测试一下@After方法

@Aspect
@Component
public class HttpAspect {

    @Before("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log(){
        System.out.println(11111);

    }

    @After("execution(public * com.imooc.controller.GirlController.*(..))")
    public void doAfter(){
        System.out.println(2222);

    }

然后运行一下,看一下控制台的代码,先是执行了@Before方法,然后执行了GirlController方法,最后执行了@After方法。

现在我们发现我们在@Before和@After的注解中写了许多重复的代码,这样是非常不好的,所以下面我们用另外一种方法书写:

   @Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
    public void log(){
    }
    
    @Before("log()")
    public void doBefore(){
        System.out.println(1111);
    }
    @After("log()")
    public void doAfter(){
        System.out.println(2222);
    }

这里我们使用了@Pointcut,定义了一个公用的方法,然后在下面的注解中调用这个方法。运行代码验证也是成功的。

现在我们不再使用system进行打印,改用log进行打印,下面看一下操作流程:

   private final static Logger logger= LoggerFactory.getLogger(HttpAspect.class);

这里我们导入的是slf4j的日志,然后在下面我们直接调用即可,例如:

@Before("log()")
public void doBefore(){
   logger.info("111111111111");
}
@After("log()")
public void doAfter(){
    logger.info("22222222222");
}

经过测试成功,这里不再赘述测试过程!

测试成功,那我们就要正式使用它了!

首先编写以下代码:

  @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request= attributes.getRequest();

        //请求url
        logger.info("url={}",request.getRequestURL());

        //请求方式:GET POST...
        logger.info("method={}",request.getMethod());

        //客户端ip
        logger.info("ip={}",request.getRemoteAddr());

        //请求的那个类的方法
        String className=joinPoint.getTarget().getClass().getName();
        String methodName=joinPoint.getSignature().getName();
        logger.info("class-method={}",className+"."+methodName+"()");

        //请求参数
        logger.info("args={}",joinPoint.getArgs());
    }

即我们在程序启动前获取请求的url、请求的方式、请求的方法名等,并且将他们打印出来,下面运行一下测试结果:

这里还是使用postman测试,然后查看控制台的结果图如下:

我们已经打印出来了我们上面所需要的信息。参数没有的原因是因为我们在这个get方法中没有传参!下面我们换个带参数的测试以下:

这里我们带着参数id=7进行查询,查看控制台结果:

我们可以看到参数也被打印出来了!

那么我们现在思考一个功能,如何把查询出来的结果返回呢?下面我们进行编码:

  @AfterReturning(returning ="object",pointcut = "log()")
    public void doAfterReturning(Object object){
        logger.info("response={}",object);

    }

下面我们再运行程序进行测试:

查看控制台结果如下:

返回的结果已经被打印出来了,如果我们想打印具体的内容可以这样操作:

在Girl实体类中添加toString方法如下:

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

然后在HttpAspect类中编码如下:

   @AfterReturning(returning ="object",pointcut = "log()")
    public void doAfterReturning(Object object){
        logger.info("response={}",object.toString());

    }

这样就可以打印出来具体内容如下:

response=Girl{id=7, cupSize='A', age=18}

关于AOP 的内容的学习就先到这里!!

猜你喜欢

转载自blog.csdn.net/MagicMHD/article/details/82378954