Spring 面向切面编程 第2关:使用环绕通知统计所有带参方法的执行时间

28 篇文章 9 订阅

目录

任务描述

相关知识

环绕通知

环绕通知和前后通知的区别

编程要求

测试说明

参考代码


任务描述

上一个关卡我们已经学会了怎么使用前后置通知统计出博客系统中博客类中每个业务方法的执行时长。那么环绕通知又是怎么使用的呢?

本关任务:使用环绕通知统计出目标类中所有带参方法运行时长。

相关知识

为了完成本关任务,你需要学习环绕通知。

环绕通知

环绕通知是最为强大的通知,它能够让你编写的逻辑将被通知的目标方法完全包裹起来。实际上就像在一个通知方法中同时编写前置通知和后置通知。定义通知的时候在通知方法中添加了入参ProceedingJoinPoint,这个参数是必须写的。因为需要在通知中使用ProceedingJoinPoint.proceed()调用目标方法。

  1. @Around("切点")
  2. public void around(ProceedingJoinPoint point) throws InterruptedException {
  3. //目标方法执行前
  4. System.out.println(" 环绕通知前");
  5. try {
  6. //执行目标方法
  7. point.proceed();
  8. } catch (Throwable throwable) {
  9. throwable.printStackT\frace();
  10. }
  11. //目标方法执行后
  12. System.out.println(" 环绕通知后");
  13. }

环绕通知和前后通知的区别

  • 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知是不能决定的,他们只是在方法的调用前后执行通知而已,即目标方法肯定是要执行的;

  • 环绕通知可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。而后置方法是无法办到的,因为他是在目标方法返回值后调用。

编程要求

请仔细阅读右侧代码,根据方法内的提示,在切面类(BlogAdvice)中的Begin - End区域内进行代码补充,其中切点已经定义好,不能修改,在此基础上使用环绕通知把目标类(BlogService)中所有有参方法的执行时间统计出来,目标类在右侧代码文件区域可见。

为了便于评测,我们手动指定程序执行前后的时间,执行前时间2019.1.1 00:00:00,执行后时间2019.1.1 00:01:00。后台IoC容器对象会自动获取目标类实例并调用目标类中所有方法。

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

预期输出:

业务功能一

程序a执行耗时60000


开始你的任务吧,祝你成功!

参考代码

package Educoder;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;

@Component("BlogAdvice")
@Aspect
public class BlogAdvice {
    //定义切点
    @Pointcut("execution(* Educoder.BlogService.service*(..))")
    public void My() {
    }
	
	//定义环绕通知,实现统计目标类所有带参方法运行时长
    @Around("My()")
    public void around(ProceedingJoinPoint point) throws ParseException, InterruptedException {
        /**********   Begin   **********/
        String startStr = "2019.1.1 00:00:00";
        String endStr = "2019.1.1 00:01:00";
         if(point.getArgs().length>0){
           SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
           long start = sdf.parse(startStr).getTime();
            try {
                point.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
           long end = sdf.parse(endStr).getTime();
           System.out.println("程序a执行耗时" + (end - start));
       }
		/**********   End   **********/
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

于建章

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值