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、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数