SpringBoot中使用AOP实现计算Service执行时间

1、增加POM.XML的依赖架包

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

2、编写AOP切面主体类
如:LogServiceTakeTime
 1 package com.leecx.aop;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 import org.aspectj.lang.annotation.*;
 6 import org.slf4j.Logger;
 7 import org.slf4j.LoggerFactory;
 8 import org.springframework.stereotype.Component;
 9 
10 /**
11  * <p>Title:</p>
12  * <p>Description:service的方法执行需要多少时间统计</p>
13  * <p>Copyright:Copyright (c) 2018</p>
14  * <p>Company:东软集团股份有限公司</p>
15  * CreateDate:2018/4/18 0018 下午 23:09
16  * Author:段美林[duanml@neusoft.com]
17  * Version:1.0
18  */
19 //申明主体类,定义切面主体类
20 @Aspect
21 @Component
22 public class LogServiceTakeTime {
23     
24     private final static Logger log = LoggerFactory.getLogger(LogServiceTakeTime.class);
25 
26     @Pointcut("execution(* com.leecx.service..*.*(..))")
27     public void performance(){
28     }
29 
30     @Around("performance()")
31     public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
32         
33         //记录起始时间 
34         long begin = System.currentTimeMillis();
35         Object result = "";
36         /** 执行目标方法 */
37         try{
38             result= joinPoint.proceed();
39         }
40         catch(Exception e){
41             log.error("日志记录发生错误, errorMessage: {}", e.getMessage());
42         }
43         finally{
44             /** 记录操作时间 */
45             long took = System.currentTimeMillis() - begin;
46             if (took >= 10000) {
47                 log.error("Service 执行时间为: {}秒", took);
48 //                log.error("Controller 执行时间为: {}毫秒", took);
49             } else if (took >= 5000) {
50                 log.warn("Service 执行时间为: {}秒", took);
51 //                log.warn("Controlle r执行时间为: {}毫秒", took);
52             } else  if (took >= 3000) {
53                 log.info("Service执行时间为: {}秒", took);
54 //                log.info("Controller 执行时间为: {}毫秒", took);
55             }
56             // TODO 日志保存到MongoDB中
57         }
58         return result;
59     }
60     
61     @Before("performance()")
62     public void doBefore(JoinPoint joinPoint) throws Throwable {
63         // 接收到请求,记录请求内容
64         log.info("doBefore");
65     }
66     
67     @AfterReturning(returning = "ret", pointcut = "performance()")
68     public void doAfterReturning(Object ret) throws Throwable {
69         // 处理完请求,返回内容
70         log.info("doAfterReturning");
71     }
72     
73 }
说明:
1、在类的主体上加上注解定义切面并申明 @Aspect 定义切面
2、@Pointcut("execution(* com.leecx.service..*.*(..))") 定义切入点,一般使用表达式申明切入的范围
如com.leecx.service 包下的所有方法都会被拦截切面到
3、@Before:切入点开始执行前处理的方法
4、@After:切入点结尾执行的方法
5、@AfterReturning:在切入点return数据后执行的方法(一般用于对返回数据的包装)
6、@Around:在切入点前后执行的方法
7、@AfterThrowing:抛出异常执行的方法

题外话:

在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut”切入点”


例如定义切入点表达式 execution (* com.sample.service.impl..*. *(..))


execution()是最常用的切点函数,其语法如下所示:


整个表达式可以分为五个部分:


1、execution(): 表达式主体。


2、第一个*号:表示返回类型, *号表示所有的类型。


3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。


4、第二个*号:表示类名,*号表示所有的类。


5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

 
原文地址:https://www.cnblogs.com/yinfengjiujian/p/8878658.html