springboot使用@Aspect实现AOP记录日志讲解 您所在的位置:网站首页 aspect类作用 springboot使用@Aspect实现AOP记录日志讲解

springboot使用@Aspect实现AOP记录日志讲解

2023-05-24 22:54| 来源: 网络整理| 查看: 265

AOPAOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。在日常开发当中经常用来记录日志,方法跟踪、事务,权限等

切面方法说明: @Aspect -- 作用是把当前类标识为一个切面供容器读取@Pointcut -- (切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式@Before -- 标识一个前置增强方法,相当于BeforeAdvice的功能@AfterReturning -- 后置增强,相当于AfterReturningAdvice,方法退出时执行@AfterThrowing -- 异常抛出增强,相当于ThrowsAdvice@After -- final增强,不管是抛出异常或者正常退出都会执行@Around -- 环绕增强,相当于MethodInterceptor  

引入AOP依赖

org.springframework.boot spring-boot-starter-aop

 

定义一个切面--TestAspect

@Aspect @Component @Slf4j public class TestAspect { //com.kzj.kzj_rabbitmq.controller 包中所有的类的所有方法切面 //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.*.*(..))") //只针对 MessageController 类切面 //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.MessageController.*(..))") //统一切点,对com.kzj.kzj_rabbitmq.controller及其子包中所有的类的所有方法切面 @Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller..*.*(..))") public void Pointcut() { } //前置通知 @Before("Pointcut()") public void beforeMethod(JoinPoint joinPoint){ log.info("调用了前置通知"); } //@After: 后置通知 @After("Pointcut()") public void afterMethod(JoinPoint joinPoint){ log.info("调用了后置通知"); } //@AfterRunning: 返回通知 rsult为返回内容 @AfterReturning(value="Pointcut()",returning="result") public void afterReturningMethod(JoinPoint joinPoint,Object result){ log.info("调用了返回通知"); } //@AfterThrowing: 异常通知 @AfterThrowing(value="Pointcut()",throwing="e") public void afterReturningMethod(JoinPoint joinPoint, Exception e){ log.info("调用了异常通知"); } //@Around:环绕通知 @Around("Pointcut()") public Object Around(ProceedingJoinPoint pjp) throws Throwable { log.info("around执行方法之前"); Object object = pjp.proceed(); log.info("around执行方法之后--返回值:" +object); return object; } }

 

添加测试用Controller

@RestController @Slf4j public class MessageController { @RequestMapping(value="/send_message",produces = "text/json;") public String send_message(MessagePojo pojo) throws Exception { log.info("执行了controller.send_message方法"); return JSON.toJSONString(pojo); } }

 

测试:在浏览器输入:http://localhost:9999/send_message?delay=15&className=B

可看到打印

 

 

可以看到,aspect类内部的 advice 将按照以下的顺序进行执行

 

 

下面是项目中实战-使用AOP打印日志和效率监听(记录请求参数和返回结果和方法运行总时间)

@Aspect @Component @Slf4j public class TestAspect { //com.kzj.kzj_rabbitmq.controller 包中所有的类的所有方法切面 //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.*.*(..))") //只针对 MessageController 类切面 //@Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller.MessageController.*(..))") //统一切点,对com.kzj.kzj_rabbitmq.controller及其子包中所有的类的所有方法切面 @Pointcut("execution(public * com.kzj.kzj_rabbitmq.controller..*.*(..))") public void Pointcut() { } //@Around:环绕通知 @Around("Pointcut()") public Object Around(ProceedingJoinPoint pjp) throws Throwable { Map data = new HashMap(); //获取目标类名称 String clazzName = pjp.getTarget().getClass().getName(); //获取目标类方法名称 String methodName = pjp.getSignature().getName(); //记录类名称 data.put("clazzName",clazzName); //记录对应方法名称 data.put("methodName",methodName); //记录请求参数 data.put("params",pjp.getArgs()); //开始调用时间 // 计时并调用目标函数 long start = System.currentTimeMillis(); Object result = pjp.proceed(); Long time = System.currentTimeMillis() - start; //记录返回参数 data.put("result",result); //设置消耗总时间 data.put("consumeTime",time); System.out.println(data); return result; } }

 

 原文:https://blog.csdn.net/u010096717/article/details/82221263



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有